PluginProbe
MBE eShip / trunk
MBE eShip vtrunk
2.8.1 trunk 1.0.0 1.1.0 1.1.3 1.2.1 1.2.2 1.3.0 1.4.0 1.4.1 1.5.0 1.5.1 1.5.2 1.6.0 1.7.0 1.7.1 2.0.0 2.0.1 2.0.2 2.0.3 2.0.4 2.1.0 2.1.1 2.1.2 2.2.1 All 37 releases
mail-boxes-etc / mail-boxes-etc.php

mail-boxes-etc.php in MBE eShip trunk, at mail-boxes-etc.php

3,150 lines 141.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: MBE eShip
4 Description: Mail Boxes Etc. Online MBE Plugin integration for main Ecommerce platforms.
5 Version: 2.8.1
6 Author: MBE Worldwide S.p.A.
7 Author URI: https://www.mbeglobal.com/
8 Text Domain: mail-boxes-etc
9 WC requires at least: 6.2
10 WC tested up to: 10.5
11 Domain Path: /languages
12 */
13
14 use MbeExceptions\ApiRequestException;
15 use MbeExceptions\DbException;
16 use Metaboxes\DynamicPackagesData;
17
18 if ( ! defined( 'MBE_ESHIP_ID' ) ) {
19 define( "MBE_ESHIP_ID", "mbe_eship" );
20 }
21
22 if ( ! defined( 'MBE_ESHIP_PLUGIN_DIR' ) ) {
23 define( "MBE_ESHIP_PLUGIN_DIR", plugin_dir_path( __FILE__ ) );
24 }
25
26 if ( ! defined( 'MBE_ESHIP_PLUGIN_URL' ) ) {
27 define( "MBE_ESHIP_PLUGIN_URL", plugin_dir_url( __FILE__ ) );
28 }
29
30 if ( ! defined( 'MBE_ESHIP_PLUGIN_OLD_LOG_DIR' ) ) {
31 define( "MBE_ESHIP_PLUGIN_OLD_LOG_DIR", MBE_ESHIP_PLUGIN_DIR . 'log' );
32 }
33
34 if ( ! function_exists( 'get_plugin_data' ) ) {
35 defined( 'ABSPATH' ) || exit;
36 require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
37 }
38 $plugin_data = get_plugin_data( __FILE__, false, false );
39
40 /** Plugin version */
41 if ( ! defined( 'MBE_ESHIP_PLUGIN_VERSION' ) ) {
42 define( "MBE_ESHIP_PLUGIN_VERSION", $plugin_data['Version'] );
43 }
44
45 /** Plugin Name */
46 if ( ! defined( 'MBE_ESHIP_PLUGIN_NAME' ) ) {
47 define( "MBE_ESHIP_PLUGIN_NAME", $plugin_data['Name'] );
48 }
49
50 /** MBE Elink Database version */
51 if ( ! defined( 'MBE_ESHIP_DATABASE_VERSION_OPTION' ) ) {
52 define( 'MBE_ESHIP_DATABASE_VERSION_OPTION', 'mbe_eship_db_version' );
53 }
54 if ( ! defined( 'MBE_ESHIP_DATABASE_VERSION' ) ) {
55 define( 'MBE_ESHIP_DATABASE_VERSION', '1.2.0' );
56 }
57
58 if ( ! defined( 'MBE_E_LINK_DEBUG_LOG' ) ) {
59 define( 'MBE_E_LINK_DEBUG_LOG', true );
60 }
61
62 /** MBE GEL Proximity **/
63 if ( ! defined( 'MBE_ESTIMATE_DELIVERY_POINT_LABELING_SERVICES' ) ) {
64 define( 'MBE_ESTIMATE_DELIVERY_POINT_LABELING_SERVICES', [ 'NMDP' ] );
65 }
66
67 if ( ! defined( 'MBE_ESTIMATE_DELIVERY_POINT_PRENEGOTIATED_SERVICES' ) ) {
68 define( 'MBE_ESTIMATE_DELIVERY_POINT_PRENEGOTIATED_SERVICES', [ 'GPP' ] );
69 }
70
71 if ( ! defined( 'MBE_ESTIMATE_DELIVERY_POINT_SERVICES' ) ) {
72 define( 'MBE_ESTIMATE_DELIVERY_POINT_SERVICES', array_merge( MBE_ESTIMATE_DELIVERY_POINT_LABELING_SERVICES, MBE_ESTIMATE_DELIVERY_POINT_PRENEGOTIATED_SERVICES ) );
73 }
74
75 if ( ! defined( 'MBE_ESTIMATE_DELIVERY_POINT_SERVICES_REGEXP' ) ) {
76 define( 'MBE_ESTIMATE_DELIVERY_POINT_SERVICES_REGEXP', '/' . ( implode( '|', MBE_ESTIMATE_DELIVERY_POINT_SERVICES ) ) . '/' );
77 }
78
79 if ( ! defined( 'MBE_DELIVERY_POINT_SERVICE' ) ) {
80 define( 'MBE_DELIVERY_POINT_SERVICE', 'MDPS' );
81 }
82 if ( ! defined( 'MBE_DELIVERY_POINT_SERVICE_METHOD' ) ) {
83 define( 'MBE_DELIVERY_POINT_SERVICE_METHOD', MBE_ESHIP_ID . ':' . MBE_DELIVERY_POINT_SERVICE );
84 }
85 if ( ! defined( 'MBE_DELIVERY_POINT_DESCRIPTION' ) ) {
86 define( 'MBE_DELIVERY_POINT_DESCRIPTION', 'Delivery Point' );
87 }
88 if ( ! defined( 'MBE_DELIVERY_POINT_WEIGHT_LIMIT' ) ) {
89 define( 'MBE_DELIVERY_POINT_WEIGHT_LIMIT', 35 );
90 }
91
92 if ( ! defined( 'MBE_SCHEMA_FLAG_OPTION' ) ) {
93 define( 'MBE_SCHEMA_FLAG_OPTION', MBE_ESHIP_ID . '_' . 'need_default_values' );
94 }
95
96 if ( ! defined( 'WOOCOMMERCE_MBE_TABS_PAGE' ) ) {
97 define( 'WOOCOMMERCE_MBE_TABS_PAGE', 'woocommerce_mbe_tabs' );
98 }
99
100 if ( ! defined( 'WOOCOMMERCE_MBE_TABS_PICKUP_PAGE' ) ) {
101 define( 'WOOCOMMERCE_MBE_TABS_PICKUP_PAGE', 'pickup_batches_tabs' );
102 }
103
104 if ( ! defined( 'WOOCOMMERCE_MBE_TABS_PICKUP_PAGE' ) ) {
105 define( 'WOOCOMMERCE_MBE_TABS_PICKUP_PAGE', 'pickup_batches_tabs' );
106 }
107
108 // REST API ENDPOINT CONSTANT
109 if ( ! defined( 'MBE_WC_REST_API_NAMESPACE' ) ) {
110 define( 'MBE_WC_REST_API_NAMESPACE', 'wc/v3' );
111 }
112 if ( ! defined( 'MBE_REST_API_ENDPOINT_SET_SHIPPING_STATUS' ) ) {
113 define( 'MBE_REST_API_ENDPOINT_SET_SHIPPING_STATUS', '/mbe/order/set-shipping-status' );
114 }
115 if ( ! defined( 'MBE_WC_REST_API_USERNAME' ) ) {
116 define( 'MBE_WC_REST_API_USERNAME', MBE_ESHIP_ID . '_api_user' );
117 }
118 if ( ! defined( 'MBE_WC_REST_API_USER_EMAIL' ) ) {
119 define( 'MBE_WC_REST_API_USER_EMAIL', 'mbeapiuser@mbeglobal.com' );
120 }
121 if ( ! defined( 'MBE_WC_REST_API_USER_ROLE' ) ) {
122 define( 'MBE_WC_REST_API_USER_ROLE', MBE_ESHIP_ID . '_rest_api_user' );
123 }
124 if ( ! defined( 'MBE_WC_REST_API_ORDER_STATUS_DELIVERED' ) ) {
125 define( 'MBE_WC_REST_API_ORDER_STATUS_DELIVERED', 'wc-mbe-api-delivered' );
126 }
127 if ( ! defined( 'MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION' ) ) {
128 define( 'MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION', 'Delivered MBE' );
129 }
130
131 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Helper/Data.php' );
132 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Helper/Logger.php' );
133 //require_once(MBE_E_LINK_PLUGIN_DIR . '/lib/Helper/Tracking.php');
134 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Helper/Csv.php' );
135 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Helper/Rates.php' );
136 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Traits/Mbe_Entity_Model_Trait.php' );
137 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Traits/ShipmentActions.php' );
138 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Interfaces/EntityModelInterface.php' );
139 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Factories/CsvEntityFactory.php' );
140 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Factories/CsvEditorEntityFactory.php' );
141 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/CsvShipping.php' );
142 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/CsvPackage.php' );
143 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/CsvPackageProduct.php' );
144 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/CsvPickupAddress.php' );
145 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/PickupCustomData.php' );
146
147 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Metaboxes/DepartmentAddressData.php' );
148 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Metaboxes/AdvancedReturnAddressData.php' );
149 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Metaboxes/DynamicPackagesData.php' );
150 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Mbe/MbeWs.php' );
151 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Mbe/MbeSoapClient.php' );
152 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/Ws.php' );
153 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Model/Carrier.php' );
154 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/Exceptions/MbeExceptions.php' );
155 require_once( MBE_ESHIP_PLUGIN_DIR . 'backward_compatibility/array_column.php' );
156
157 //if ( ! class_exists( '\Dompdf\Dompdf' ) ) {
158 // require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/dompdf/autoload.inc.php' );
159 //}
160
161 require_once( MBE_ESHIP_PLUGIN_DIR . 'lib/vendor/autoload.php' );
162
163 function mbe_eship_is_old_elink_plugin_active() {
164 $activePlugins = array_keys( get_plugins() );
165 $oldPlugin = array_filter( $activePlugins, function ( $item ) {
166 return preg_match( '/mail-boxes-etc.php/', $item );
167 } );
168
169 return is_plugin_active( array_values( $oldPlugin )[0] );
170 }
171
172 /**
173 * Plugin activation check
174 */
175 function mbe_eship_activation_check() {
176 if ( ! class_exists( 'SoapClient' ) ) {
177 deactivate_plugins( basename( __FILE__ ) );
178 wp_die( 'Sorry, but you cannot run this plugin, it requires the <a href="http://php.net/manual/en/class.soapclient.php">SOAP</a> support on your server/hosting to function.' );
179 }
180 }
181
182 /**
183 * Transfer the settings from the old plugin to the new ones
184 * @return void
185 */
186 function mbe_eship_update_new_settings_check() {
187 global $wpdb;
188 $logger = new Mbe_Shipping_Helper_Logger();
189
190 $schemaFlagOption = MBE_ESHIP_ID . '_' . 'need_new_settings';
191 $oldOption = get_option( Mbe_Shipping_Helper_Data::MBE_ELINK_SETTINGS );
192 $mbeNeedUpdate = ! ( get_option( $schemaFlagOption ) === 'no' ) && ! empty( $oldOption );
193 // To check if plugin was already configured but options weren't migrated yet
194 $notConfigured = empty( get_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_ALLOWED_SHIPMENT_SERVICES ) );
195 $csv_rates_model = new Mbe_Shipping_Model_Csv_Shipping();
196 $csv_package_model = new Mbe_Shipping_Model_Csv_Package();
197 $csv_package_product_model = new Mbe_Shipping_Model_Csv_Package_Product();
198
199 // TODO: Check if the impact can be mitigated moving this line inside the if
200 $tableExist = $csv_rates_model->tableExists() && $csv_package_model->tableExists() && $csv_package_product_model->tableExists();
201
202 if ( $mbeNeedUpdate && $tableExist && $notConfigured ) {
203
204 $logger->log( 'Migrating from MBE e-Link --- Starting', true );
205 // try {
206
207 $logger->log( 'Migrating from MBE e-Link --- Options', true );
208 foreach ( $oldOption as $key => $value ) {
209 update_option( MBE_ESHIP_ID . '_' . $key, $value );
210 }
211
212 $logger->log( 'Migrating from MBE e-Link --- Login', true );
213 $wsUser = $oldOption[ Mbe_Shipping_Helper_Data::XML_PATH_WS_USERNAME ];
214 $wsPwd = $oldOption[ Mbe_Shipping_Helper_Data::XML_PATH_WS_PASSWORD ];
215
216 // Set advanced login mode
217 if ( ! empty( $wsUser ) && ! empty( $wsPwd ) ) {
218 update_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_LOGIN_MODE, Mbe_Shipping_Helper_Data::MBE_LOGIN_MODE_ADVANCED );
219 update_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_LOGIN_LINK_ADV, true );
220 }
221
222 $logger->log( 'Migrating from MBE e-Link --- Configuration mode', true );
223 $csvMode = $oldOption[ Mbe_Shipping_Helper_Data::XML_PATH_SHIPMENTS_CSV_MODE ];
224 if ( $csvMode <> Mbe_Shipping_Helper_Data::MBE_CSV_MODE_DISABLED ) {
225 update_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_COURIER_CONFIG_MODE, Mbe_Shipping_Helper_Data::MBE_COURIER_MODE_CSV );
226 } else if ( $oldOption['mbe_enable_custom_mapping'] === 'yes' ) {
227 update_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_COURIER_CONFIG_MODE, Mbe_Shipping_Helper_Data::MBE_COURIER_MODE_MAPPING );
228 } else {
229 update_option( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_COURIER_CONFIG_MODE, Mbe_Shipping_Helper_Data::MBE_COURIER_MODE_SERVICES );
230 }
231
232 // Migrate CSV tables
233 $logger->log( 'Migrating from MBE e-Link --- Csv Tables', true );
234 // TODO: move tablexists here ?
235 $csvTables = [
236 $csv_rates_model->getTableName() => 'mbeshippingrate',
237 $csv_package_model->getTableName() => 'mbe_shipping_standard_packages',
238 $csv_package_product_model->getTableName() => 'mbe_shipping_standard_package_product',
239 ];
240
241 foreach ( $csvTables as $key => $value ) {
242 // Check if old table exists
243 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
244 if ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s", $wpdb->prefix . $value ) ) == $wpdb->prefix . $value ) {
245 $wpdb->query( $wpdb->prepare( "INSERT INTO %i SELECT * FROM %i", $key, $wpdb->prefix . $value ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
246 }
247 }
248
249 update_option( $schemaFlagOption, 'no' );
250
251 $logger->log( 'Migrating from MBE e-Link --- Complete', true );
252 // } catch ( Exception $e ) {
253 //
254 // }
255 } else if ( ! ( get_option( $schemaFlagOption ) === 'no' ) && empty( $oldOption ) ) {
256 $logger->log( 'Migrating from MBE e-Link --- Old options are missing ' );
257 } else if ( $mbeNeedUpdate && ! $notConfigured ) {
258 $logger->log( 'Migrating from MBE e-Link --- No migration, Plugin already configured ' );
259 }
260 }
261
262 function mbe_eship_check_log_folder_htaccess() {
263 $helper = new Mbe_Shipping_Helper_Data();
264 $dirPath = trailingslashit( $helper->getMbeLogDir() );
265 $filePath = $dirPath . '.htaccess';
266 if ( ! file_exists( $filePath ) ) {
267 $helper->createHtaccessDenyAll( $dirPath );
268 }
269 }
270
271 function mbe_eship_rest_api_key_check() {
272 if ( is_admin() ) {
273 $logger = new Mbe_Shipping_Helper_Logger();
274 $user_id = username_exists( MBE_WC_REST_API_USERNAME );
275
276 if ( $user_id && email_exists( MBE_WC_REST_API_USER_EMAIL ) ) {
277 $helper = new Mbe_Shipping_Helper_Data();
278
279 if ( ! $helper->hasApiKey( $user_id ) ) {
280 try {
281 mbe_eship_generate_and_send_api_key( $user_id );
282 } catch ( DbException $e ) {
283 $logger->log( 'REST API Check - Generate and Send Api Key EXCEPTION: ' . $e->getMessage() );
284 }
285 }
286 } else {
287 $logger->log( 'REST API Check - Generate and Send Api Key - User/Email missing' );
288 }
289 }
290 }
291
292 function mbe_eship_uninstall_db_options() {
293 global $wpdb;
294 $csv_rates_model = new Mbe_Shipping_Model_Csv_Shipping();
295 $csv_package_model = new Mbe_Shipping_Model_Csv_Package();
296 $csv_package_product_model = new Mbe_Shipping_Model_Csv_Package_Product();
297 $pickup_custom_data_model = new Mbe_Shipping_Model_Pickup_Custom_Data();
298
299 // Delete all the tables
300 $tables = [
301 $csv_rates_model->getTableName(),
302 $csv_package_model->getTableName(),
303 $csv_package_product_model->getTableName(),
304 $pickup_custom_data_model->getTableName(),
305 ];
306
307 // Remove "old plugin" tables too if any
308 array_push( $tables,
309 $wpdb->prefix . 'mbe_shipping_standard_package_product',
310 $wpdb->prefix . 'mbe_shipping_standard_packages',
311 $wpdb->prefix . 'mbeshippingrate' );
312
313 foreach ( $tables as $table ) {
314 $wpdb->query( $wpdb->prepare( "DROP TABLE IF EXISTS %i", $table ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
315 }
316
317 // Delete the REST API User, Role and Keys if any
318 $userLogin = MBE_WC_REST_API_USERNAME;
319 $mbeApiRole = MBE_WC_REST_API_USER_ROLE;
320
321 if ( username_exists( $userLogin ) ) {
322 $user = get_user_by( 'login', $userLogin );
323 if ( ! wp_delete_user( $user->ID ) ) {
324 error_log( MBE_ESHIP_PLUGIN_NAME . ': REST API User Deletion - User not deleted' );
325 }
326 remove_role( $mbeApiRole );
327 } else {
328 error_log( MBE_ESHIP_PLUGIN_NAME . ': REST API User Deletion - User not found' );
329 }
330 error_log( MBE_ESHIP_PLUGIN_NAME . ': REST API User Deletion - User, Role and Keys deleted successfully' );
331
332 // Delete all the options
333 $wpdb->query( "DELETE FROM $wpdb->options WHERE option_name LIKE '" . MBE_ESHIP_ID . "\_%'" ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
334
335 // Delete the "old plugin" db version option, since we are removing the tables
336 delete_option( 'mbe_elink_db_version' );
337
338 // Remove all pickup meta items from the orders
339 $queryMeta = $wpdb->prepare( "DELETE FROM $wpdb->order_itemmeta where meta_key in (%s, %s, %s)", Mbe_Shipping_Helper_Data::META_FIELD_IS_PICKUP_SHIPPING, Mbe_Shipping_Helper_Data::META_FIELD_PICKUP_BATCH_ID, Mbe_Shipping_Helper_Data::META_FIELD_PICKUP_CUSTOM_DATA_ID );
340 $wpdb->query( $queryMeta ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
341
342 }
343
344 function mbe_eship_install_db() {
345
346 $helper = new Mbe_Shipping_Helper_Data();
347 $currentVersion = get_option( MBE_ESHIP_DATABASE_VERSION_OPTION ) ?: '0';
348
349 if ( version_compare( $currentVersion, MBE_ESHIP_DATABASE_VERSION, '<' ) ) {
350 require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
351 $dbDelta = dbDelta( get_mbe_elink_db_schema() );
352
353 // ADD conditions to verify if the database has been correctly updated accordingly to the last schema changes
354 // If only a new table is added , $updateCondition can be kept as "true" but mbe_elink_db_tables_exist() must be updated
355 $updateCondition = true;
356
357 if ( mbe_elink_db_tables_exist() && $updateCondition ) {
358 update_option( MBE_ESHIP_DATABASE_VERSION_OPTION, MBE_ESHIP_DATABASE_VERSION );
359 }
360 }
361 }
362
363 function mbe_elink_db_tables_exist() {
364 $csv_rates_model = new Mbe_Shipping_Model_Csv_Shipping();
365 $csv_package_model = new Mbe_Shipping_Model_Csv_Package();
366 $csv_package_product_model = new Mbe_Shipping_Model_Csv_Package_Product();
367 $pickup_custom_data_model = new Mbe_Shipping_Model_Pickup_Custom_Data();
368
369 return $csv_rates_model->tableExists()
370 && $csv_package_model->tableExists()
371 && $csv_package_product_model->tableExists()
372 && $pickup_custom_data_model->tableExists();
373 }
374
375 function get_mbe_elink_db_schema() {
376 $csv_rates_model = new Mbe_Shipping_Model_Csv_Shipping();
377 $csv_package_model = new Mbe_Shipping_Model_Csv_Package();
378 $csv_package_product_model = new Mbe_Shipping_Model_Csv_Package_Product();
379 $pickup_custom_data_model = new Mbe_Shipping_Model_Pickup_Custom_Data();
380
381 return $csv_rates_model->getSqlCreate()
382 . $csv_package_model->getSqlCreate()
383 . $csv_package_product_model->getSqlCreate()
384 . $pickup_custom_data_model->getSqlCreate();
385 }
386
387 function mbe_eship_update_db_check() {
388 $action = sanitize_text_field( $_REQUEST['action'] ?? '' );
389 if ( ! empty( $action ) && $action !== 'deactivate' ) {
390 mbe_eship_install_db();
391 }
392 }
393
394 function declare_compatibility() {
395 // HPOS
396 if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
397 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
398 }
399 // BLOCK CHECKOUT
400 if ( class_exists( '\Automattic\WooCommerce\Utilities\FeaturesUtil' ) ) {
401 \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, false );
402 }
403 }
404
405
406 // ** REST API Management ** //
407 // ** User, role, apikey creation and deletion ** //
408
409 function mbe_rest_api_user_creation_and_sync_to_mol() {
410 $logger = new Mbe_Shipping_Helper_Logger();
411
412 if ( ! class_exists( 'woocommerce' ) ) {
413 $logger->log( 'REST API User Creation - Woocommerce is not active' );
414
415 return false;
416 }
417
418 // Create the MBE REST API user role if not exists
419 add_role( MBE_WC_REST_API_USER_ROLE, strtoupper( str_replace( '_', ' ', MBE_ESHIP_ID ) ) . ' REST API User'
420 // ,array(
421 // 'read' => true,
422 // 'edit_posts' => false,
423 // 'delete_posts' => false,
424 // add capabilities
425 // )
426 );
427
428 // Create the MBE REST API user with a random password (no backend login is required for api access)
429 $password = wc_rand_hash();
430
431 if ( ! username_exists( MBE_WC_REST_API_USERNAME ) && ! email_exists( MBE_WC_REST_API_USER_EMAIL ) ) {
432 $user_id = wp_create_user( MBE_WC_REST_API_USERNAME, $password, MBE_WC_REST_API_USER_EMAIL );
433 if ( ! is_wp_error( $user_id ) ) {
434 // Assign the custom role to the user
435 $user = new WP_User( $user_id );
436 $user->set_role( MBE_WC_REST_API_USER_ROLE );
437 try {
438 mbe_eship_generate_and_send_api_key( $user_id );
439 } catch ( DbException $e ) {
440 $logger->log( 'REST API User Creation - Generate Api Key EXCEPTION: ' . $e->getMessage() );
441 }
442 } else {
443 /** @var WP_Error $user_id */
444 $logger->log( 'REST API User Creation - EXCEPTION: ' . $user_id->get_error_message() );
445 }
446 } else {
447 $logger->log( 'REST API User Creation - User already exists' );
448 }
449 }
450
451 /**
452 * @param Mbe_Shipping_Helper_Data $helper
453 * @param $user_id
454 * @param Mbe_Shipping_Helper_Logger $logger
455 * @param Mbe_Shipping_Model_Ws $ws
456 *
457 * @return void
458 * @throws DbException
459 */
460 function mbe_eship_generate_and_send_api_key( $user_id ): void {
461 $helper = new Mbe_Shipping_Helper_Data();
462 $ws = new Mbe_Shipping_Model_Ws();
463 $logger = new Mbe_Shipping_Helper_Logger();
464
465 try {
466 $stepMessage = 'generateMbeRestApiKey';
467 $apiKeys = $helper->generateMbeRestApiKey( $user_id );
468
469 $logger->log( 'REST API Creation - New WooCommerce API Key created' );
470
471 $stepMessage = 'sendRestApiCredentials';
472 $result = $ws->sendRestApiCredentials( base64_encode( $apiKeys['key'] . ':' . $apiKeys['secret'] ) );
473
474 } catch ( ApiRequestException $e ) {
475 $logger->log( 'REST API Creation - Send Api Key EXCEPTION: ' . $stepMessage . ' - ' . $e->getMessage() );
476 // delete the api key so it will be regenerated by the control hooked on plugin save
477 $helper->removeMbeRestApiKey( $user_id );
478 } catch ( \Exception $e ) {
479 $logger->log( 'REST API Creation - EXCEPTION: ' . $stepMessage . ' - ' . $e->getMessage() );
480 $helper->removeMbeRestApiKey( $user_id );
481 }
482 }
483
484 register_uninstall_hook( __FILE__, 'mbe_eship_uninstall_db_options' ); // ONLY ONE Uninstall Hook is registrable
485 register_activation_hook( __FILE__, 'mbe_eship_activation_check' );
486 register_activation_hook( __FILE__, 'mbe_eship_install_db' );
487
488
489 // ** REST API Management ** //
490 // ** User, role, apikey creation and deletion ** //
491 register_initial_settings();
492 register_activation_hook( __FILE__, 'mbe_rest_api_user_creation_and_sync_to_mol' );
493 // ** //
494
495 //register_activation_hook( __FILE__, 'mbe_eship_create_options_default' );
496 //add_action( 'plugins_loaded','mbe_eship_create_options_default' );
497 //add_action( 'plugins_loaded','mbe_eship_check_pickup_request_mode' );
498
499 add_action( 'plugins_loaded', 'mbe_eship_update_db_check', 9 );
500 add_action( 'plugins_loaded', 'mbe_eship_update_new_settings_check', 10 );
501 add_action( 'plugins_loaded', 'mbe_eship_check_log_folder_htaccess', 10 );
502 add_action( 'before_woocommerce_init', 'declare_compatibility' );
503
504
505 /**
506 * Check if WooCommerce is active
507 */
508 if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
509 if ( ! function_exists( 'mbe_e_link_get_settings_url' ) ) {
510 function mbe_e_link_get_settings_url() {
511 return version_compare( WC()->version, '2.1', '>=' ) ? "wc-settings" : "woocommerce_settings";
512 }
513 }
514
515 if ( ! function_exists( 'mbe_e_link_plugin_override' ) ) {
516 add_action( 'plugins_loaded', 'mbe_e_link_plugin_override' );
517 function mbe_e_link_plugin_override() {
518 if ( ! function_exists( 'WC' ) ) {
519 function WC() {
520 return $GLOBALS['woocommerce'];
521 }
522 }
523 }
524 }
525
526 if ( ! class_exists( 'mbe_e_link_wooCommerce_shipping_setup' ) ) {
527 class mbe_e_link_wooCommerce_shipping_setup {
528 use \Traits\ShipmentActions;
529
530 protected $helper;
531
532 public function __construct() {
533 add_filter( 'woocommerce_get_settings_pages', array( $this, 'load_custom_settings_tab' ) );
534
535 // Check if Pickup request activation flag is set and in case force the default value setter to run
536 add_action( 'mbe_eship_custom_settings_loaded', array(
537 $this,
538 'mbe_eship_check_pickup_default_options'
539 ) );
540
541 // Check if MBE Easy Duty request activation flag is set and in case force the default value setter to run
542 add_action( 'mbe_eship_custom_settings_loaded', array(
543 $this,
544 'mbe_eship_check_tax_and_duties_default_options'
545 ) );
546
547 // Check default values for settings
548 add_action( 'mbe_eship_custom_settings_loaded', array(
549 $this,
550 'mbe_eship_create_options_default'
551 ), 20 );
552
553 // Add settings link in the plugin list
554 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array(
555 $this,
556 'plugin_action_links'
557 ) );
558 // Add MBE shipping method to WooCommerce but remove the tab from WooCommerce => Settings => Shipping
559 add_filter( 'woocommerce_shipping_methods', array( $this, 'wf_mbe_wooCommerce_shipping_methods' ) );
560 add_action( 'woocommerce_shipping_init', array( $this, 'wf_mbe_wooCommerce_shipping_init' ) );
561
562 // Action for downloading log files
563 add_action( 'admin_post_mbe_download_log_files', array( $this, 'mbe_download_log_files' ) );
564 add_action( 'admin_post_mbe_download_standard_package_file', array(
565 $this,
566 'mbe_download_standard_package_file'
567 ), 10, 0 );
568 add_action( 'admin_post_mbe_download_shipping_file', array(
569 $this,
570 'mbe_download_shipping_file'
571 ), 10, 0 );
572 add_filter( 'query_vars', array( $this, 'mbe_add_query_vars' ) );
573
574 // Action for deleting log files
575 add_action( 'admin_post_mbe_delete_log_files', array( $this, 'mbe_delete_log_files' ) );
576
577 // Action for generating API KEY
578 // add_action( 'admin_post_mbe_generate_api_key', array( $this, 'mbe_generate_api_key' ) );
579
580 //Action for new settings
581 add_action( 'admin_post_mbe_sign_in', array( $this, 'mbe_sign_in' ) );
582 add_action( 'admin_post_mbe_goto_advanced_login', array( $this, 'mbe_goto_advanced_login' ) );
583 add_action( 'admin_post_mbe_reset_login', array( $this, 'mbe_reset_login' ) );
584
585 // Action to download single order pickup manifest
586 add_action( 'admin_post_mbe_download_pickup_manifest', array( $this, 'mbe_download_pickup_manifest' ) );
587
588 // Action to download multiple waybill showing partial errors (called by add_order_list via JS when "reload-download" parameter is set)
589 add_action( 'admin_post_mbe_download_multiple_waybill', array(
590 $this,
591 'mbe_download_multiple_waybill'
592 ) );
593
594 // Action to download delivery point single order waybill
595 add_action( 'admin_post_mbe_download_delivery_point_waybill', array(
596 $this,
597 'mbe_download_delivery_point_waybill'
598 ) );
599
600 // Add menu
601 add_action( 'admin_menu', array( $this, 'add_mbe_tab' ) );
602
603 // Load translations
604 add_action( 'plugins_loaded', array( $this, 'wan_load_wf_shipping_mbe' ) );
605
606 // Add Delivery Point Field to Admin Order details view
607 add_action( 'woocommerce_admin_order_data_after_billing_address', array(
608 $this,
609 'wf_mbe_delivery_point_show_meta_field'
610 ), 10, 1 );
611
612 // Add box in the order detail
613 add_action( 'wp_loaded', array( $this, 'wf_mbe_wooCommerce_shipping_init_box' ) );
614
615 // Get default data for pickup from MOL when loading pickup settings page or before creating a new pickup shipment
616 // add_action('woocommerce_before_settings_'. MBE_ESHIP_ID , array($this, 'mbe_woocommerce_get_pickup_default_data'));
617 add_action( MBE_ESHIP_ID . '_before_output_section_mbe_pickup', array(
618 $this,
619 'mbe_woocommerce_get_pickup_default_data'
620 ), 5 );
621 add_action( MBE_ESHIP_ID . '_before_create_pickup', array(
622 $this,
623 'mbe_woocommerce_get_pickup_default_data'
624 ), 5 );
625
626 // Send default data for pickup to MOL
627 add_action( 'woocommerce_update_options_' . MBE_ESHIP_ID . '_mbe_pickup', array(
628 $this,
629 'mbe_woocommerce_set_pickup_default_data'
630 ) );
631
632 // Action to create a return shipment
633 add_action( 'admin_post_mbe_create_return_shipment', array( $this, 'mbe_create_return_shipment' ) );
634 add_action( MBE_ESHIP_ID . '_before_create_advanced_return', array(
635 $this,
636 'mbe_woocommerce_get_advanced_return_address_data'
637 ), 5 );
638
639 // //Action to edit a pickup batch
640 // add_action('admin_post_mbe_edit_pickup', array($this, 'pickup_data_form_page_handler'));
641
642 // Action to ship a pickup batch
643 add_action( 'admin_post_mbe_send_pickup', array( $this, 'mbe_send_pickup' ) );
644
645 // Action to delete a pickup batch
646 add_action( 'admin_post_mbe_delete_pickup_custom_data', array(
647 $this,
648 'mbe_delete_pickup_custom_data'
649 ) );
650
651 // Action to detach an order from a pickup batch
652 add_action( 'admin_post_mbe_detach_order_from_batch', array( $this, 'mbe_detach_order_from_batch' ) );
653
654 // Action to check batch items after detach
655 add_action( MBE_ESHIP_ID . '_after_detach', array( $this, 'mbe_after_detach_check_pickup_items' ) );
656
657 // Action to check pickup status after deleting the pickup addresses
658 add_action( MBE_ESHIP_ID . '_csv_editor_deleted', array(
659 $this,
660 'mbe_after_delete_pickup_address_disable_pickup_if_no_default_address'
661 ), 10, 2 );
662
663 // Script to manage custom mbebuttons actions
664 add_action( 'admin_enqueue_scripts', array( $this, 'mbe_helper_scripts' ) );
665
666 $this->helper = new Mbe_Shipping_Helper_Data();
667 if ( $this->helper->isEnabled() ) {
668 add_action( 'wp_enqueue_scripts', array( $this, 'mbe_gel_proximity_scripts' ) );
669
670 add_action( 'closure_event', array( $this, 'automatic_closure' ) );
671 add_action( 'woocommerce_settings_saved', array( $this, 'add_cron_job' ) );
672 add_action( 'woocommerce_admin_updated', array( $this, 'mbe_error_notice' ) );
673
674 //Add admin notice
675 add_action( 'admin_notices', array( $this, 'mbe_shipping_admin_notices' ) );
676
677 // Add label "Free" to Frontend if the price is 0
678 add_filter( 'woocommerce_cart_shipping_method_full_label', array(
679 $this,
680 'wf_mbe_wooCommerce_set_free_label'
681 ), 10, 2 );
682
683 // Create shipping automatically on status processing
684 add_action( 'woocommerce_order_status_processing', array( $this, 'mbe_update_tracking' ), 10, 2 );
685
686 // Create shipping manually
687 add_filter( 'woocommerce_order_actions', array( $this, 'add_order_meta_box_actions' ), 10, 2 );
688 add_action( 'woocommerce_order_action_mbe_shipping_creation', array(
689 $this,
690 'process_order_meta_box_actions'
691 ) );
692
693 // Add frontend tracking
694 add_action( 'woocommerce_order_details_after_order_table', array(
695 $this,
696 'woocommerce_order_details_tracking'
697 ) );
698
699 // Add frontend GEL proximity delivery points map
700 add_action( 'woocommerce_after_shipping_rate', array(
701 $this,
702 'wf_mbe_wooCommerce_shipping_gel_delivery_point_map'
703 ), 10, 2 );
704
705 // Add filter to hide custom order item metakeys
706 add_filter( 'woocommerce_order_item_get_formatted_meta_data', array(
707 $this,
708 'wf_mbe_wooCommerce_shipping_hide_custom_order_meta_keys'
709 ), 10, 2 );
710
711 // Add Delivery point dataset to the checkout fields list
712 // add_filter( 'woocommerce_checkout_fields', array(
713 // $this,
714 // 'wf_mbe_delivery_point_add_selected_location_field'
715 // ) );
716
717 // Add Delivery point address form field validation
718 add_action( 'woocommerce_after_checkout_validation', array(
719 $this,
720 'wf_mbe_delivery_point_validation'
721 ), 10, 2 );
722
723 // Set Delivery Point address as order's shipping address
724 add_filter( 'woocommerce_checkout_posted_data', array(
725 $this,
726 'wf_mbe_delivery_point_set_shipping_address'
727 ) );
728
729 // Set Delivery Point shipment meta-field value for the "old" shortcode checkout
730 add_action( 'woocommerce_checkout_update_order_meta', array(
731 $this,
732 'wf_mbe_delivery_point_set_meta_field'
733 ), 10, 2 );
734
735 // Set Order shipping method code as a meta-field for the "old" shortcode checkout
736 add_action( 'woocommerce_checkout_create_order_shipping_item', array(
737 $this,
738 'wf_mbe_shipping_method_code_set_meta_field'
739 ), 10, 4 );
740
741
742 add_action( 'woocommerce_checkout_update_order_review', array(
743 $this,
744 'wf_mbe_delivery_point_set_meta_field_review'
745 ) );
746
747 // Update package payload for dynamic shipping cost base on selected delivery point
748 add_filter( 'woocommerce_package_rates', array(
749 $this,
750 'wf_mbe_delivery_point_update_package_for_cost_recalculation'
751 ), 10, 2 );
752
753 // Remove the delivery point session variable
754 add_action( 'woocommerce_checkout_order_created', array(
755 $this,
756 'wf_mbe_remove_delivery_point_session_variable'
757 ) );
758 add_action( 'woocommerce_cart_emptied', array(
759 $this,
760 'wf_mbe_remove_delivery_point_session_variable'
761 ) );
762 add_action( 'woocommerce_cart_is_empty', array(
763 $this,
764 'wf_mbe_remove_delivery_point_session_variable'
765 ) );
766
767 // Set Custom Mapping metafield value for the "old" shortcode checkout
768 add_action( 'woocommerce_checkout_update_order_meta', array(
769 $this,
770 'wf_mbe_wooCommerce_shipping_custom_mapping_meta_field'
771 ) );
772
773 // Set Custom Mapping metafield value for the "new" blocks checkout
774 add_action( 'woocommerce_store_api_checkout_update_order_meta', array(
775 $this,
776 'wf_mbe_wooCommerce_shipping_custom_mapping_meta_field_checkout_block'
777 ) );
778
779 // Add track ID to transational emails
780 add_action( 'woocommerce_email_order_details', array(
781 $this,
782 'mbe_woocommerce_email_track_id'
783 ), 20, 4 );
784
785 // Check the pickup request mode <=> shipping mode
786 add_action( 'woocommerce_settings_page_init', array(
787 $this,
788 'mbe_eship_check_pickup_request_mode'
789 ) );
790
791 // Check if the MBE Easy Duty must be disabled
792 add_action( 'woocommerce_settings_page_init', array( $this, 'mbe_eship_check_tax_and_duties' ) );
793
794 // Set or update pickup data on shipment creation
795 add_action( MBE_ESHIP_ID . '_before_create_pickup', array( $this, 'mbe_edit_pickup_data' ) );
796
797 // Set or update department address data in shipment list
798 add_action( MBE_ESHIP_ID . '_add_department_data', array(
799 $this,
800 'mbe_edit_department_address_data'
801 ) );
802
803 // Action to select a department address for the pickup order
804 add_action( 'admin_post_mbe_select_department_address_pickup', array(
805 $this,
806 'mbe_select_department_address_pickup'
807 ) );
808
809 // Action to set or update package data for the order/shipment
810 add_action( MBE_ESHIP_ID . '_edit_dynamic_packages_data', array(
811 $this,
812 'mbe_edit_dynamic_packages_data'
813 ) );
814
815 // Show MBE Easy Duty in Checkout shortcodes
816 add_action( 'woocommerce_review_order_before_submit', array(
817 $this,
818 'mbe_show_tax_and_duties_checkout_message'
819 ) );
820
821 if($this->helper->isEnabledTaxAndDuties()) {
822 add_action( 'woocommerce_cart_calculate_fees', array(
823 $this,
824 'mbe_eship_add_tax_and_duties_fee'
825 ) );
826 }
827
828 // Check insurance services selected when saving settings
829 add_action( 'woocommerce_settings_save_' . MBE_ESHIP_ID, array(
830 $this,
831 'mbe_check_insurance_mode_selected'
832 ) );
833
834 // Add REST API endpoint for Tracking
835 add_action( 'rest_api_init', array(
836 $this,
837 'register_woocommerce_mbe_order_shipping_status_route'
838 ) );
839 // Add REST API Status for Orders
840 add_filter( 'wc_order_statuses', array( $this, 'mbe_eship_add_order_delivered_status' ) );
841
842 add_action( 'init', array( $this, 'mbe_eship_register_post_status' ), 9 );
843 add_action( 'admin_head', array( $this, 'mbe_eship_style_delivered_status' ) );
844
845
846 // Check REST API User/Key is enabled. Run only after MBE settings are saved, doesn't run for other WC settings
847 add_action( 'woocommerce_settings_save_' . MBE_ESHIP_ID, function () {
848 if ( ! has_action( 'woocommerce_settings_saved', 'mbe_eship_rest_api_key_check' ) ) {
849 add_action( 'woocommerce_settings_saved', 'mbe_eship_rest_api_key_check', 5 );
850 }
851 } );
852 // Remove the Check REST API once executed (using priority)
853 add_action( 'woocommerce_settings_saved', function () {
854 if ( has_action( 'woocommerce_settings_saved', 'mbe_eship_rest_api_key_check' ) ) {
855 remove_action( 'woocommerce_settings_saved', 'mbe_eship_rest_api_key_check' );
856 }
857 }, 10 );
858
859 }
860 }
861
862 function mbe_eship_style_delivered_status() {
863 if ( ! ( is_admin() &&
864 ( get_current_screen()->id === 'woocommerce_page_wc-orders' || get_current_screen()->id === 'edit-shop_order' )
865 ) ) {
866 return;
867 } // Exit
868
869 $deliveredStatus = substr( MBE_WC_REST_API_ORDER_STATUS_DELIVERED, 3 );
870
871 ?>
872 <style>
873 .order-status.status-<?php echo sanitize_title( $deliveredStatus ); ?> {
874 background: #c6e1c6;
875 color: #5b841b;
876 }
877 </style>
878 <?php
879 }
880
881 public function mbe_eship_add_order_delivered_status( array $statuses ) {
882 $statuses[ MBE_WC_REST_API_ORDER_STATUS_DELIVERED ] = __( MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION, 'mail-boxes-etc' );
883
884 return $statuses;
885 }
886
887 public function mbe_eship_register_draft_order_post_status( array $statuses ) {
888 $statuses[ MBE_WC_REST_API_ORDER_STATUS_DELIVERED ] = $this->mbe_eship_get_post_status_properties();
889
890 return $statuses;
891 }
892
893 function mbe_eship_register_post_status() {
894 $is_registered = get_post_stati( [ 'name' => MBE_WC_REST_API_ORDER_STATUS_DELIVERED ] );
895 if ( empty( $is_registered ) ) {
896 register_post_status(
897 MBE_WC_REST_API_ORDER_STATUS_DELIVERED,
898 $this->mbe_eship_get_post_status_properties()
899 );
900 }
901 }
902
903 function mbe_eship_get_post_status_properties() {
904 return [
905 'label' => __( MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION, 'mail-boxes-etc' ),
906 'public' => true,
907 'exclude_from_search' => false,
908 'show_in_admin_all_list' => true,
909 'show_in_admin_status_list' => true,
910 /* %s: number of orders */
911 'label_count' => _n_noop( __( MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION ) . ' <span class="count">(%s)</span>', __( MBE_WC_REST_API_ORDER_STATUS_DELIVERED_DESCRIPTION ) . ' <span class="count">(%s)</span>', 'mail-boxes-etc' ),
912 ];
913 }
914
915 function register_woocommerce_mbe_order_shipping_status_route() {
916 register_rest_route( MBE_WC_REST_API_NAMESPACE, MBE_REST_API_ENDPOINT_SET_SHIPPING_STATUS, array(
917
918 'methods' => WP_REST_Server::EDITABLE,
919 'callback' => array( $this, 'rest_api_handle_mbe_order_shipping_status_endpoint' ),
920 'permission_callback' => array( $this, 'rest_api_mbe_api_key_permission_check' )
921 ) );
922 }
923
924 // Authentication callback function
925 function rest_api_mbe_api_key_permission_check( $request ) {
926 $logger = new Mbe_Shipping_Helper_Logger();
927 $logger->log( 'REST API Endpoint - Permission check' );
928
929 // Get the custom MOL request header
930 $MolApiKeyHeader = $request->get_header( 'authorization-api-key' ) ?? '';
931
932 if ( empty( $MolApiKeyHeader ) ) {
933 return new WP_Error( 'rest_forbidden', 'You do not have permission to access this endpoint.', array( 'status' => 403 ) );
934 }
935
936 $apiKey = explode( ':', base64_decode( $MolApiKeyHeader ) );
937
938 // Set the keys to be used in WC_REST_Authentication
939 $_GET['consumer_key'] = $apiKey[0] ?? '';
940 $_GET['consumer_secret'] = $apiKey[1] ?? '';
941
942 $auth = new WC_REST_Authentication();
943 $userId = $auth->authenticate( false );
944
945 if ( ! empty( $userId ) ) {
946 $logger->log( 'REST API Endpoint - Permission check - OK' );
947
948 return true;
949 }
950 $logger->logVar( $request, 'REST API Endpoint - Permission check - Failed' );
951
952 return new WP_Error( 'rest_forbidden', 'You do not have permission to access this endpoint.', array( 'status' => 403 ) );
953 }
954
955 function rest_api_handle_mbe_order_shipping_status_endpoint( $request ) {
956 // Handle the request and return a response
957 $logger = new Mbe_Shipping_Helper_Logger();
958 $requestParameters = $request->get_params();
959 $logger->log( 'REST API Endpoint - Incoming request' );
960
961 $isAdvancedReturn = false;
962
963 if ( ! empty( $requestParameters ) ) {
964 $trackingNumber = trim( sanitize_text_field( $requestParameters[0]['mbeTrackingNumber'] ?? '' ) );
965 $mbeStatus = $requestParameters[0]['mbeStatus'];
966
967 $trackingNumber = preg_replace( '/-\d{1,2}\s*$/', '', $trackingNumber );
968 $logger->log( 'REST API Endpoint - Tracking Number: ' . $trackingNumber . ' - Status code: ' . $mbeStatus );
969
970 $orders = [];
971 if ( ! empty( $trackingNumber ) ) {
972 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
973 $orders = wc_get_orders( [
974 'meta_key' => Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER,
975 'meta_value' => $trackingNumber
976 ] );
977 if ( empty( $orders ) ) { // Check if it matches a return shipment
978 $orders = wc_get_orders( [
979 'meta_key' => Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_RETURN_TRACKING_NUMBER,
980 'meta_value' => $trackingNumber
981 ] );
982 $isAdvancedReturn = true;
983 }
984
985 } else {
986 $trackingFilter = array(
987 'post_type' => 'shop_order',
988 'post_status' => 'wc-%',
989 'nopaging' => 'true',
990 'fields' => 'ids',
991 'meta_key' => Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER,
992 'meta_value' => $trackingNumber,
993 );
994 $query = new WP_Query( $trackingFilter );
995 $orderIds = $query->get_posts();
996 if ( empty( $orderIds ) ) {
997 $trackingFilter = array(
998 'post_type' => 'shop_order',
999 'post_status' => 'wc-%',
1000 'nopaging' => 'true',
1001 'fields' => 'ids',
1002 'meta_key' => Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_RETURN_TRACKING_NUMBER,
1003 'meta_value' => $trackingNumber,
1004 );
1005 $query = new WP_Query( $trackingFilter );
1006 $orderIds = $query->get_posts();
1007 $isAdvancedReturn = true;
1008 }
1009
1010 $orders[] = wc_get_order( $orderIds[0] );
1011
1012 }
1013 }
1014
1015 // there should be only one order for each master tracking number, so we get the first one
1016 $order = $orders[0] ?? null;
1017 if ( ! empty( $order ) ) {
1018 try {
1019
1020 if ( $isAdvancedReturn ) {
1021 $this->helper->setOrderMbeAdvancedReturnTrackingStatus( $order, serialize( $requestParameters[0] ) );
1022 }
1023
1024 // Update the the order status only for shop shipments and not for return shipments
1025 if ( ! $isAdvancedReturn && $this->helper->setOrderMbeTrackingStatus( $order, serialize( $requestParameters[0] ) ) !== false ) {
1026 $deliveredStatus = substr( MBE_WC_REST_API_ORDER_STATUS_DELIVERED, 3 );
1027
1028 // Update order status if the shipment has been delivered and the status wasn't yet updated
1029 if ( 1 == $mbeStatus && $order->get_status() !== $deliveredStatus ) {
1030 $order->set_status( $deliveredStatus );
1031 $order->save();
1032 $logger->log( 'Order delivered status updated successfully' );
1033 }
1034
1035 $message = 'Shipment status updated successfully.';
1036 $logger->log( $message );
1037
1038 $data = array(
1039 'message' => $message,
1040 'status' => 'success',
1041 'request-param' => $request->get_params()
1042 );
1043 }
1044
1045 return new WP_REST_Response( $data, 200 );
1046
1047 } catch ( Exception $e ) {
1048 $message = 'An error occured : ' . $e->getMessage();
1049 $logger->log( $message );
1050
1051 $data = array(
1052 'message' => $message,
1053 'status' => 'Error',
1054 'request-parameters' => $requestParameters
1055 );
1056
1057 return new WP_REST_Response( $data, 500 );
1058 }
1059 } else {
1060 $message = 'Order not found';
1061 $logger->log( $message );
1062
1063 $data = array(
1064 'message' => $message,
1065 'status' => 'Error',
1066 'request-parameters' => $requestParameters
1067 );
1068
1069 return new WP_REST_Response( $data, 404 );
1070 }
1071 }
1072
1073 $message = 'Empty payload';
1074 $logger->log( $message );
1075 $data = array(
1076 'message' => $message,
1077 'status' => 'Error',
1078 'request-parameters' => $requestParameters
1079 );
1080
1081 return new WP_REST_Response( $data, 400 );
1082 }
1083
1084 function mbe_gel_proximity_scripts() {
1085 $logger = new Mbe_Shipping_Helper_Logger();
1086
1087 if ( ! empty( $this->helper->getGelProximityMerchantCode() ) ) {
1088 wp_enqueue_script( MBE_ESHIP_ID . '-gel-proxmity-map-js', Mbe_Shipping_Helper_Data::GEL_PROXIMITY_URL . '/sdk/latest.js', '', rand() );
1089 wp_enqueue_script( MBE_ESHIP_ID . '-gel-proxmity-map-initialization', MBE_ESHIP_PLUGIN_URL . 'lib/js/gel-proximity-map-initilization.js', '', rand() );
1090 wp_add_inline_script( MBE_ESHIP_ID . '-gel-proxmity-map-initialization', 'const ' . 'mbe_gel_proxmity_data = ' . json_encode( array(
1091 'urlEndUser' => $this->helper->getGelProxymityUrlEndUser(),
1092 'merchantCode' => $this->helper->getGelProximityMerchantCode(),
1093 'apiKey' => $this->helper->getGelProxymityApiKey(),
1094 'locale' => get_user_locale(),
1095 'debug' => $this->helper->debug()
1096 ) ), 'before' );
1097 } else {
1098 $logger->log( 'GEL scripts not initialized, missing Merchant Code' );
1099 }
1100 }
1101
1102 function mbe_helper_scripts() {
1103 wp_enqueue_script( MBE_ESHIP_ID . '-helper-scripts-js', MBE_ESHIP_PLUGIN_URL . 'lib/js/mbe-helper-scripts.js', '', rand() );
1104 }
1105
1106 function load_custom_settings_tab( $settings ) {
1107 // if( ! class_exists(Mbe_Settings::class)) {
1108 // $settings[] = include __DIR__ . '/includes/class-mbe-settings-page.php';
1109 // } else {
1110 // $settings = Mbe_Settings();
1111 // }
1112
1113 $mbeSettings = include __DIR__ . '/includes/class-mbe-settings-page.php';
1114 $settings[] = $mbeSettings;
1115
1116 do_action( 'mbe_eship_custom_settings_loaded', $mbeSettings );
1117
1118 return $settings;
1119
1120 }
1121
1122 function mbe_eship_create_options_default( $mbeSettingsPage ) {
1123 // Check if it's needed and not already running
1124 if ( ! ( get_option( MBE_SCHEMA_FLAG_OPTION ) === 'no' ) && ! get_transient( MBE_ESHIP_ID . '_set_options_default' ) ) {
1125 $logger = new Mbe_Shipping_Helper_Logger();
1126 $logger->log( 'Saving settings default value - Starting', true );
1127 // set transient to flag it's running.
1128 set_transient( MBE_ESHIP_ID . '_set_options_default', 'yes', MINUTE_IN_SECONDS * 5 );
1129
1130 // Include settings so that we can run through defaults.
1131 if ( ! class_exists( WC_Settings_Page::class ) ) {
1132 require_once( WP_PLUGIN_DIR . '/woocommerce/includes/admin/settings/class-wc-settings-page.php' );
1133 }
1134
1135 // $mbeSettingsPage = include_once __DIR__ . '/includes/class-mbe-settings-page.php';
1136 $sections = $mbeSettingsPage->get_sections();
1137 // Remove the Welcome page from the list
1138 unset( $sections[''] );
1139
1140 $subsections = array_unique( array_keys( $sections ) );
1141
1142 foreach ( $subsections as $subsection ) {
1143 foreach ( $mbeSettingsPage->get_settings_for_section( $subsection ) as $value ) {
1144 if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
1145 add_option( $value['id'], $value['default'] );
1146 }
1147 }
1148 }
1149
1150 update_option( MBE_SCHEMA_FLAG_OPTION, 'no' );
1151 delete_transient( MBE_ESHIP_ID . '_set_options_default' );
1152 $logger->log( 'Saving settings default value - Done', true );
1153 }
1154 }
1155
1156 function mbe_eship_check_pickup_default_options() {
1157 $helper = new Mbe_Shipping_Helper_Data();
1158 $logger = new Mbe_Shipping_Helper_Logger();
1159 // Check if Activation flag exists and if not run the default value setter
1160 if ( ! $helper->hasOption( Mbe_Shipping_Helper_Data::XML_PATH_PICKUP_REQUEST_ENABLED ) && $helper->isEnabledThirdPartyPickups() ) {
1161 update_option( MBE_SCHEMA_FLAG_OPTION, 'yes' );
1162 $logger->log( 'Updating schema flag to run default value setter for Pickup request' );
1163 }
1164 }
1165
1166 function mbe_eship_check_pickup_request_mode() {
1167 $logger = new Mbe_Shipping_Helper_Logger();
1168
1169 // Disable pickup if Shipping mode is not coherent
1170 // $disablePickup = !$this->helper->isEnabledThirdPartyPickups() || (
1171 // $this->helper->getShipmentsCreationMode() === Mbe_Shipping_Helper_Data::MBE_CREATION_MODE_AUTOMATICALLY
1172 // && $this->helper->getPickupRequestMode() === Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_MANUAL
1173 // );
1174
1175 // Disable pickup if the user doesn't have the rights set in MOL
1176 $disablePickup = ! $this->helper->isEnabledThirdPartyPickups();
1177
1178 if ( $disablePickup && $this->helper->getPickupRequestEnabled() ) {
1179 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_PICKUP_REQUEST_ENABLED, 0 );
1180 // WC_Admin_Settings::add_error(
1181 // __( 'Pickup request cannot be enabled, please check the settings', 'mail-boxes-etc' )
1182 // . ':' . __( 'Shipments creation in MBE Online - Mode', 'mail-boxes-etc' )
1183 // . ' or '
1184 // . __( 'Pickup Request - Mode', 'mail-boxes-etc' )
1185 // . ' ' . __( 'or the MBE Online options for third party pickup', 'mail-boxes-etc' )
1186 // );
1187 // $logger->log( 'Pickup mode and Shipping mode are not set correctly, disabling pickup' );
1188 WC_Admin_Settings::add_error(
1189 __( 'Pickup request cannot be enabled, please check the settings', 'mail-boxes-etc' )
1190 . ' ' . __( 'for third party pickup in MBE Online', 'mail-boxes-etc' )
1191 );
1192 $logger->log( 'Pickup is disabled in MOL, disabling pickup' );
1193 }
1194
1195 // Disable pickup if the pickup mode is auto and a default address is not set
1196 if ( $this->helper->getPickupRequestEnabled()
1197 && ! $this->helper->hasDefaultPickupAddress()
1198 && $this->helper->getPickupRequestMode() === Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC
1199 ) {
1200 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_PICKUP_REQUEST_ENABLED, 0 );
1201 WC_Admin_Settings::add_error( __( 'Pickup request cannot be enabled, please set a default pickup address', 'mail-boxes-etc' ) );
1202 $logger->log( 'Default pickup address missing, disabling pickup' );
1203 }
1204
1205 // If Pickup is still enabled and shipping mode is automatic but pickup mode is still manual, set pickup mode to automatic too
1206 if ( $this->helper->getPickupRequestEnabled()
1207 && $this->helper->getShipmentsCreationMode() === Mbe_Shipping_Helper_Data::MBE_CREATION_MODE_AUTOMATICALLY
1208 && $this->helper->getPickupRequestMode() === Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_MANUAL
1209 ) {
1210 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_PICKUP_REQUEST_MODE, Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC );
1211 }
1212 }
1213
1214 function mbe_check_insurance_mode_selected() {
1215 $helper = new Mbe_Shipping_Helper_Data();
1216 $requestSelectedServices = wc_clean( $_REQUEST[ MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_ALLOWED_SHIPMENT_SERVICES ] ?? [] );
1217 $lastInsuranceServicesSelected = '';
1218
1219 foreach ( $requestSelectedServices as $request_selected_service ) {
1220 $insuranceService = $helper->isShippingWithInsurance( $request_selected_service );
1221 if ( ! empty( $insuranceService ) && ( $insuranceService !== $lastInsuranceServicesSelected && ! empty( $lastInsuranceServicesSelected ) ) ) {
1222 $helper->logErrorAndSetWCAdminMessage( __( 'Only one between MBE SafaValue, MBE SafeValue4Business and Courier Insurance can be activated at the same time' ) );
1223 $helper->setPostOption( MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_ALLOWED_SHIPMENT_SERVICES, $helper->getAllowedShipmentServicesArray() );
1224
1225 return false;
1226 } else {
1227 $lastInsuranceServicesSelected = $insuranceService ?: $lastInsuranceServicesSelected;
1228 }
1229 }
1230 }
1231
1232 function mbe_error_notice() {
1233 require_once( ABSPATH . 'wp-admin/includes/screen.php' );
1234 if ( is_admin() ) {
1235 if ( ! isset( get_current_screen()->id ) || get_current_screen()->id !== 'woocommerce_page_wc-settings' ) {
1236 return;
1237 } //only show on 'order' pages
1238 echo '<div class="notice notice-error"><p>Warning - If you modify template files this could cause problems with your website.</p></div>';
1239 }
1240 }
1241
1242 /**
1243 * Plugin cron job
1244 */
1245 function automatic_closure() {
1246 $logger = new Mbe_Shipping_Helper_Logger();
1247 $logger->log( 'Cron automatic_closure' );
1248 include_once 'includes/cron.php';
1249 }
1250
1251 function remove_cron_job() {
1252 wp_clear_scheduled_hook( 'closure_event' );
1253 }
1254
1255 public function add_cron_job() {
1256 $logger = new Mbe_Shipping_Helper_Logger();
1257 $time = $this->helper->getShipmentsClosureTime();
1258 if ( $this->helper->isEnabled() && $this->helper->isClosureAutomatically() ) {
1259 $closureTime = strtotime( "today $time " . wp_timezone_string() );
1260 $cron_jobs = get_option( 'cron' );
1261 $array = array_column( $cron_jobs, 'closure_event' );
1262 if ( ! empty( $array ) ) {
1263 $index = array_search( array( 'closure_event' => $array[0] ), $cron_jobs );
1264 $scheduledTime = date( 'H:i:s', $index );
1265 if ( $scheduledTime != $time ) {
1266 wp_clear_scheduled_hook( 'closure_event' );
1267 wp_schedule_event( $closureTime, 'daily', 'closure_event' );
1268 $logger->log( "Cron automatic closure set at: $time " . wp_timezone_string() );
1269 }
1270 } else {
1271 wp_schedule_event( $closureTime, 'daily', 'closure_event' );
1272 $logger->log( "Cron automatic closure set at: $time " . wp_timezone_string() );
1273 }
1274 } else {
1275 wp_clear_scheduled_hook( 'closure_event' );
1276 }
1277 }
1278
1279 /**
1280 * Add settings link in the plugin list
1281 */
1282
1283 public function plugin_action_links( $links ) {
1284 $plugin_links = array(
1285 '<a href="' . admin_url( 'admin.php?page=' . mbe_e_link_get_settings_url() . '&tab=' . MBE_ESHIP_ID ) . '">' . __( 'Settings', 'mail-boxes-etc' ) . '</a>',
1286 );
1287
1288 return array_merge( $plugin_links, $links );
1289 }
1290
1291 /**
1292 * Add shipping method to WooCommerce
1293 */
1294
1295 public function wf_mbe_wooCommerce_shipping_methods( $methods ) {
1296 $methods[] = 'mbe_shipping_method';
1297
1298 return $methods;
1299 }
1300
1301 public function wf_mbe_wooCommerce_shipping_init() {
1302 include_once( 'includes/class-mbe-shipping.php' );
1303 }
1304
1305 /**
1306 * Add box in the order detail
1307 */
1308
1309 public function wf_mbe_wooCommerce_shipping_init_box() {
1310 include_once( 'includes/class-mbe-tracking-admin.php' );
1311 }
1312
1313 /**
1314 * Add menu tab in WooCommerce
1315 */
1316
1317 function add_mbe_tab() {
1318 add_submenu_page( 'woocommerce', __( 'MBE Shipments List', 'mail-boxes-etc' ), __( 'MBE Shipments List', 'mail-boxes-etc' ), 'manage_woocommerce', WOOCOMMERCE_MBE_TABS_PAGE, array(
1319 $this,
1320 'add_order_list'
1321 ) );
1322
1323 add_submenu_page( null, __( 'MBE CSV Editor', 'mail-boxes-etc' ), __( 'MBE CSV Editor', 'mail-boxes-etc' ), 'manage_woocommerce', 'woocommerce_mbe_csv_tabs', array(
1324 $this,
1325 'add_csv_list'
1326 ) );
1327
1328 add_submenu_page( null, __( 'Add new', 'mail-boxes-etc' ), __( 'Add new', 'mail-boxes-etc' ), 'activate_plugins', MBE_ESHIP_ID . '_csv_edit_form', array(
1329 $this,
1330 'csv_form_page_handler'
1331 ) );
1332
1333 // PICKUP Pages
1334 if ( $this->helper->isEnabledThirdPartyPickups() ) {
1335 add_submenu_page( null, __( 'MBE Pickup Batches List', 'mail-boxes-etc' ), __( 'Pickup', 'mail-boxes-etc' ), 'manage_woocommerce', MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE, array(
1336 $this,
1337 'add_pickup_batches_list'
1338 ) );
1339
1340
1341 add_submenu_page( null, __( 'MBE Pickup Data Editor', 'mail-boxes-etc' ), __( 'MBE Pickup Data Editor', 'mail-boxes-etc' ), 'manage_woocommerce', MBE_ESHIP_ID . '_pickup_data_tabs', array(
1342 $this,
1343 'pickup_data_form_page_handler'
1344 ) );
1345 }
1346
1347 //DEPARTMENT Address Selection Page
1348 if ( ! $this->helper->isCreationAutomatically() ) {
1349 add_submenu_page( null, __( 'MBE Department Data Selection', 'mail-boxes-etc' ), __( 'MBE Department Data Selection', 'mail-boxes-etc' ), 'manage_woocommerce', MBE_ESHIP_ID . '_department_address_data_tabs', array(
1350 $this,
1351 'department_address_data_form_page_handler'
1352 ) );
1353 }
1354
1355 // ADVANCED RETURN Address Data Page
1356 if ( $this->helper->canAdvancedReturn() ) {
1357 add_submenu_page( null, __( 'MBE Advanced Return Address Data', 'mail-boxes-etc' ), __( 'MBE Advanced Return Address Data', 'mail-boxes-etc' ), 'manage_woocommerce', MBE_ESHIP_ID . '_advanced_return_address_data_tabs', array(
1358 $this,
1359 'advanced_return_address_data_form_page_handler'
1360 ) );
1361 }
1362
1363 //Dynamic packages Data Page
1364 if ( ! $this->helper->isCreationAutomatically() ) {
1365 add_submenu_page( null, __( 'MBE Dynamic Packages Data', 'mail-boxes-etc' ), __( 'MBE Dynamic Packages Data', 'mail-boxes-etc' ), 'manage_woocommerce', MBE_ESHIP_ID . '_dynamic_packages_data_tabs', array(
1366 $this,
1367 'mbe_dynamic_packages_data_form_page_handler'
1368 ) );
1369 }
1370 }
1371
1372 /**
1373 * Add order list in MBE tab
1374 */
1375
1376 function add_order_list() {
1377 require_once 'includes/class-mbe-order.php';
1378 $orders = new Mbe_E_Link_Order_List_Table();
1379 $orders->prepare_items();
1380 ?>
1381
1382 <nav class="nav-tab-wrapper woo-nav-tab-wrapper">
1383 <a href="#" class="nav-tab nav-tab-active">
1384 <h2><?php esc_html_e( 'MBE Shipments List', 'mail-boxes-etc' ) ?></h2>
1385 </a>
1386 <?php if ( $this->helper->isEnabledThirdPartyPickups() ) { ?>
1387 <a href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?page=' . MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE ) ) ?>"
1388 class="nav-tab ">
1389 <h2><?php esc_html_e( 'MBE Manual Pickup', 'mail-boxes-etc' ) ?></h2>
1390 </a>
1391 <?php } ?>
1392 </nav>
1393 <div class="wrap">
1394 <?php $this->mbe_eship_wp_notification() ?>
1395
1396 <form id="certificates-filter" method="get">
1397 <input type="hidden" name="page"
1398 value="<?php echo ( ! empty( $_REQUEST['page'] ) ) ? esc_attr( wp_unslash( $_REQUEST['page'] ) ) : ''; ?>"
1399 />
1400
1401 <?php
1402 $orders->display();
1403 ?>
1404 </form>
1405 </div>
1406
1407 <?php
1408 $downloadFile = sanitize_url( $_GET['reload-download'] ?? null );
1409 if ( ! empty( $downloadFile ) && isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], WOOCOMMERCE_MBE_TABS_PAGE ) ) {
1410 $actionUrl = sprintf( "%sadmin-post.php?action=mbe_download_multiple_waybill&downloadFile=%s&nonce=%s", get_admin_url(), urlencode( $downloadFile ), wp_create_nonce( 'mbe_download_multiple_waybill' ) );
1411 echo "<script>jQuery(document).ready(mbeButtonAction(this, " . json_encode( $actionUrl ) . ",'_blank', 'false'))</script>";
1412 }
1413 }
1414
1415 function mbe_download_multiple_waybill() {
1416 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_multiple_waybill' ) ) {
1417 // Unset the session variable
1418 $downloadFile = sanitize_url( $_REQUEST['downloadFile'] );
1419 $this->helper->mbe_download_file( $downloadFile, "mbe-labels.pdf", 'application/pdf', true );
1420 }
1421 }
1422
1423 function add_pickup_batches_list() {
1424 require_once 'includes/class-mbe-pickup-batches.php';
1425 $ordersPickupBatches = new Mbe_E_Link_Pickup_Batches_List_Table();
1426 $ordersPickupBatches->prepare_items();
1427 ?>
1428
1429 <nav class="nav-tab-wrapper woo-nav-tab-wrapper">
1430 <a href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?page=' . WOOCOMMERCE_MBE_TABS_PAGE ) ) ?>"
1431 class="nav-tab ">
1432 <h2><?php esc_html_e( 'MBE Shipments List', 'mail-boxes-etc' ) ?></h2>
1433 </a>
1434 <?php if ( $this->helper->isEnabledThirdPartyPickups() ) { ?>
1435 <a href="#" class="nav-tab nav-tab-active">
1436 <h2><?php esc_html_e( 'MBE Manual Pickup', 'mail-boxes-etc' ) ?></h2>
1437 </a>
1438 <?php } ?>
1439 </nav>
1440 <div class="wrap">
1441 <?php $this->mbe_eship_wp_notification() ?>
1442
1443 <!-- <form id="certificates-filter" method="get">
1444 <input type="hidden" name="page"
1445 value="<?php /*echo ( ! empty( $_REQUEST['page'] ) ) ? esc_attr( wp_unslash( $_REQUEST['page'] ) ) : ''; */ ?>"
1446 />
1447 -->
1448 <?php $a = $ordersPickupBatches->display() ?>
1449 <!-- </form>-->
1450 </div>
1451
1452 <?php
1453 }
1454
1455 function add_csv_list() {
1456 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'woocommerce_mbe_csv_tabs' ) ) {
1457 $csvType = sanitize_text_field( $_REQUEST['csv'] ?? '' );
1458 $csvFactory = new Mbe_Csv_Editor_Model_Factory();
1459 $csv = $csvFactory->create( $csvType );
1460 $message = sanitize_text_field( $_REQUEST['message'] ?? '' );
1461 if ( ! empty( $csv ) ) {
1462 $title = $csv->get_title( false );
1463 $csv->prepare_items();
1464 if ( 'delete' === $csv->current_action() ) {
1465 $message = sprintf( __( 'Items deleted: %d', 'mail-boxes-etc' ), count( (array) wc_clean( $_REQUEST['id'] ) ) );
1466 }
1467 ?>
1468
1469 <div class="wrap">
1470 <h2><?php esc_html_e( 'MBE ' . $title . ' ' . __( 'Editor' ) ) ?>
1471 <a class="add-new-h2"
1472 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?page=' . mbe_e_link_get_settings_url() . '&tab=' . MBE_ESHIP_ID . '&section=' . $csv->get_backlink() ) ); ?>">
1473 <?php esc_html_e( 'Back to settings', 'mail-boxes-etc' ) ?>
1474 </a>
1475 </h2>
1476
1477 <?php $this->mbe_eship_wp_notification() ?>
1478 <?php if ( ! empty( $notice ) ): ?>
1479 <div id="notice" class="notice notice-error is-dismissible">
1480 <p><?php echo wp_kses_post( $notice ) ?></p></div>
1481 <?php endif; ?>
1482 <?php if ( ! empty( $message ) ): ?>
1483 <div id="message" class="notice notice-success is-dismissible">
1484 <p><?php echo wp_kses_post( $message ) ?></p></div>
1485 <?php endif; ?>
1486
1487 <form id="certificates-filter" method="get">
1488 <?php //Fields to be sent with request and bulk actions ?>
1489 <input type="hidden" name="page"
1490 value="<?php echo ( ! empty( $_REQUEST['page'] ) ) ? esc_attr( wp_unslash( $_REQUEST['page'] ) ) : ''; ?>"
1491 />
1492 <input type="hidden" name="csv"
1493 value="<?php esc_attr_e( $csvType ) ?>"
1494 />
1495 <?php $csv->display() ?>
1496 </form>
1497 </div>
1498 <?php
1499 } else {
1500 ?>
1501 <div class="wrap">
1502 <h2><?php esc_html_e( 'Missing or wrong csv type', 'mail-boxes-etc' ) ?>
1503 <a class="add-new-h2"
1504 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?page=' . mbe_e_link_get_settings_url() . '&tab=' . MBE_ESHIP_ID . '&section=mbe_general' ) ); ?>">
1505 <?php esc_html_e( 'Back to settings', 'mail-boxes-etc' ) ?>
1506 </a>
1507 </h2>
1508 </div>
1509 <?php
1510 }
1511 } else {
1512 wp_redirect( wp_get_referer() );
1513 }
1514 }
1515
1516 /**
1517 * Creation shipping manually action
1518 */
1519
1520 function add_order_meta_box_actions( $actions, $order ) {
1521 if ( is_array( $actions ) ) {
1522 // $this->>helper = new Mbe_Shipping_Helper_Data();
1523 if ( $order ) {
1524 if ( $this->helper->isMbeShipping( $order ) ) {
1525 if ( ! $this->helper->isCreationAutomatically() && ! $this->helper->hasTracking( $order->get_id() ) ) {
1526 $actions['mbe_shipping_creation'] = __( 'Create MBE shipping', 'mail-boxes-etc' );
1527 }
1528 }
1529 }
1530 }
1531
1532 return $actions;
1533 }
1534
1535 function process_order_meta_box_actions( $order ) {
1536 if ( $this->helper->isMbeShipping( $order ) ) {
1537 include_once 'includes/class-mbe-tracking-factory.php';
1538 $orderId = $this->helper->getOrderId( $order );
1539 mbe_tracking_factory::create( $orderId );
1540 }
1541 }
1542
1543
1544 public function mbe_update_tracking( $order_id ) {
1545 $order = wc_get_order( $order_id );
1546 if ( $this->helper->isEnabled() && $this->helper->isMbeShipping( $order ) && $this->helper->isCreationAutomatically() && empty( $this->helper->getTrackings( $order_id ) ) ) {
1547 // include_once 'includes/class-mbe-tracking-factory.php';
1548 // mbe_tracking_factory::create( $order_id );
1549 $pickupInfo = [];
1550 if ( $this->helper->getPickupRequestEnabled()
1551 && Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC === $this->helper->getPickupRequestMode()
1552 ) {
1553 $pickupInfo = [
1554 'is-pickup' => true,
1555 'is-batch' => false,
1556 'custom-data-id' => null,
1557 ];
1558 }
1559 $post_ids = array_map( 'absint', (array) $order_id );
1560 $this->processShipmentCreation( $post_ids, $pickupInfo );
1561 }
1562 }
1563
1564 /**
1565 * Set Free Label to Carriers
1566 */
1567
1568 public function wf_mbe_wooCommerce_set_free_label( $full_label, $method ) {
1569 if ( (float) $method->cost == 0.0 ) {
1570 return $full_label . ': ' . __( "Free", 'mail-boxes-etc' );
1571 } else {
1572 return $full_label;
1573 }
1574 }
1575
1576 public function wan_load_wf_shipping_mbe() {
1577 load_plugin_textdomain( 'mail-boxes-etc', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' );
1578 }
1579
1580 /*
1581 * Add front tracking
1582 */
1583
1584 public function woocommerce_order_details_tracking( $order ) {
1585 // $this->>helper = new Mbe_Shipping_Helper_Data();
1586 $orderId = $this->helper->getOrderId( $order );
1587 $trackings = $this->helper->getTrackings( $orderId );
1588 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
1589 $tracking_url = $order === false? '' : $order->get_meta( Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL );
1590 $trackingName = $order === false? '' : $order->get_meta( 'woocommerce_mbe_tracking_name' );
1591 } else {
1592 $tracking_url = get_post_meta( $orderId, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL, true );
1593 $trackingName = get_post_meta( $orderId, 'woocommerce_mbe_tracking_name', true );
1594 }
1595
1596 if ( $this->helper->isMbeShipping( $order ) && ! empty( $trackings ) ) {
1597 echo "<h2>" . esc_html__( 'Mail Boxes ETC Tracking', 'mail-boxes-etc' ) . "</h2>";
1598 echo '
1599 <table class="shop_table tracking_details">
1600 <thead>
1601 <tr>
1602 <th class="service-name">' . esc_html__( 'Service', 'mail-boxes-etc' ) . '</th>
1603 <th class="tracking-link">' . esc_html__( 'Tracking', 'mail-boxes-etc' ) . '</th>
1604 </tr>
1605 </thead>
1606 <tbody>';
1607 foreach ( $trackings as $track ) {
1608 echo '<tr class="order_item">
1609 <td class="tracking-name">' . esc_html( $trackingName ) . '</td>
1610 <td class="product-total"><a target="_blank" href="' . esc_attr( $tracking_url . $track ) . '">' . esc_html( $track ) . '</a></td>
1611 </tr>';
1612 }
1613 echo '</tbody></table>';
1614 }
1615 }
1616
1617 /**
1618 * Adds GEL delivery point map to the WooCommerce shipping method
1619 *
1620 * @param object $method The WooCommerce shipping method object
1621 */
1622 public function wf_mbe_wooCommerce_shipping_gel_delivery_point_map( $method ) {
1623 $mbeServiceSelected = (
1624 $this->isDeliveryPointServiceMethod( WC()->session->get( 'chosen_shipping_methods' ) )
1625 && $method->id === WC()->session->get( 'chosen_shipping_methods' )[0]
1626 );
1627
1628 if ( $mbeServiceSelected && is_checkout() ) {
1629 // Generate the delivery point GEL services list (NET_xxx codes) for GEL map initialization
1630 // $gelServices = '';
1631 // foreach ( $method->meta_data['delivery_point_services']['courier'] as $gel_service ) {
1632 // $gelServices .= "'" . $gel_service ."'" . ',';
1633 // }
1634
1635 // Generate the price parameter for GEL map initialization - manage taxes based on woocommerce settings
1636 $prenegotiatedFound = false;
1637 $labelingFound = false;
1638 $deliveryPointPrices = [ 'currencyCode' => get_woocommerce_currency() ];
1639 foreach ( array_combine( $method->get_meta_data()['delivery_point_services']['mol'], $method->get_meta_data()['delivery_point_services']['prices'] ) as $key => $value ) {
1640 if ( ! $prenegotiatedFound && in_array( $key, MBE_ESTIMATE_DELIVERY_POINT_PRENEGOTIATED_SERVICES ) ) {
1641 $deliveryPointPrices ['prenegotiated'] = (float) $value;
1642 $prenegotiatedFound = true;
1643 if ( $labelingFound ) {
1644 break;
1645 }
1646 }
1647
1648 if ( ! $labelingFound && in_array( $key, MBE_ESTIMATE_DELIVERY_POINT_LABELING_SERVICES ) ) {
1649 $deliveryPointPrices ['labeling'] = (float) $value;
1650 $labelingFound = true;
1651 if ( $prenegotiatedFound ) {
1652 break;
1653 }
1654 }
1655 }
1656
1657 if ( wc_tax_enabled() && WC()->cart->display_prices_including_tax() ) {
1658 $taxPercentage = $this->getShippingTaxPercentageFromCart();
1659
1660 if ( $taxPercentage > 0 ) {
1661 foreach (
1662 array_intersect_key( $deliveryPointPrices, [
1663 'prenegotiated' => '',
1664 'labeling' => ''
1665 ] ) as $key => $price
1666 ) {
1667 // Set the delivery point price adding taxes
1668 $deliveryPointPrices[ $key ] += $this->helper->round( $price * $taxPercentage / 100 );
1669 }
1670 }
1671 }
1672
1673 // Add the form field to the section and set value in case of delivery point selection price refresh
1674 echo '<div style="margin-bottom: 0.5em; padding-left: 20px;">';
1675 $sessionDeliveryPoint = WC()->session->get( 'mbe_delivery_point' ) ?? null;
1676 $gelProximitySelectionLabel = null;
1677 $gelProximitySelection = null;
1678
1679 if ( ! empty( $sessionDeliveryPoint ) ) {
1680 $gelProximitySelection = json_encode( (array) $sessionDeliveryPoint );
1681 $gelProximitySelectionLabel = $sessionDeliveryPoint->networkName . ', ' . $sessionDeliveryPoint->address . ', ' . $sessionDeliveryPoint->zipCode . ', ' . $sessionDeliveryPoint->city;
1682 }
1683
1684 woocommerce_form_field( 'gel-proximity-selection-label', array(
1685 'id' => 'gel-proximity-selection-label',
1686 'class' => 'woocommerce-validated',
1687 'type' => 'text',
1688 'required' => true,
1689 'custom_attributes' => array(
1690 'style' => 'font-size: 0.8em;',
1691 'readonly' => 'readonly',
1692 'onclick' => 'openGELProximityModal()'
1693 ),
1694 'placeholder' => __( 'Click to select a delivery point', 'mail-boxes-etc' ),
1695 ), $gelProximitySelectionLabel
1696 );
1697
1698 woocommerce_form_field( 'gel-proximity-selection', array(
1699 'type' => 'hidden',
1700 'id' => 'gel-proximity-selection',
1701 ), $gelProximitySelection
1702 );
1703
1704 woocommerce_form_field( 'gel-proximity-selection-update', array(
1705 'type' => 'hidden',
1706 'id' => 'gel-proximity-selection-update',
1707 ), false // alway set the field to false, tha value must be true only when posting from gel-proximity-map-initilization.js
1708 );
1709
1710 echo '<script type="text/javascript">
1711 mbeGelSDK.options.networks = ' . json_encode( $method->get_meta_data()['delivery_point_services']['courier'] ) . '
1712 mbeGelSDK.options.prices = ' . json_encode( $deliveryPointPrices ) . '
1713 </script>';
1714
1715 echo '</div>';
1716 }
1717
1718 }
1719
1720 function wf_mbe_delivery_point_validation( $data, $errors ) {
1721 if ( isset( $_POST['gel-proximity-selection'] ) && empty( $data['mbe_delivery_point_data'] ) ) {
1722 $errors->add( 'validation', __( 'Select a delivery point to proceed', 'mail-boxes-etc' ) );
1723 }
1724 }
1725
1726 function wf_mbe_delivery_point_show_meta_field( $order ) {
1727 $order_meta_delvery_point = $this->helper->getOrderDeliveryPointShipment( $order->get_id() );
1728 if ( ! empty( $order_meta_delvery_point ) ) {
1729 echo '<p><strong>' . esc_html__( 'Delivery Point' ) . ':</strong> ' . esc_html__( $order_meta_delvery_point, 'mail-boxes-etc' ) . '</p>';
1730 }
1731 }
1732
1733 function wf_mbe_delivery_point_set_meta_field( $order_id, $data ) {
1734 $logger = new Mbe_Shipping_Helper_Logger();
1735 $order = wc_get_order( $order_id );
1736 if ( $this->helper->isMbeShipping( $order ) ) {
1737 if ( ! empty( $data['mbe_delivery_point_data'] ) ) {
1738 $this->helper->setOrderDeliveryPointShipment( $order_id, 'Yes' );
1739 $this->helper->setOrderDeliveryPointCustomData( $order_id, $data['mbe_delivery_point_data'] );
1740 } else {
1741 $logger->log( __( 'Missing Access Point ID in $_POST' ) );
1742 $this->helper->setOrderDeliveryPointShipment( $order_id, 'No' );
1743 }
1744 $order->save();
1745 }
1746 }
1747
1748 function wf_mbe_shipping_method_code_set_meta_field( $item, $package_key, $package, $order) {
1749 $helper = new Mbe_Shipping_Helper_Data();
1750 $logger = new Mbe_Shipping_Helper_Logger();
1751 $item_meta = $item->get_meta('method_mbe_service_id'); /// get shipping method meta-data value
1752 if($item_meta) {
1753 return $helper->setOrderMethodMbeServiceId($order->get_id(), $item_meta, 'method_mbe_service_id');
1754 } else {
1755 $logger->log(__( 'Missing Mbe Service ID in rates meta data', 'mail-boxes-etc'));
1756 return false;
1757 }
1758 }
1759
1760 function wf_mbe_delivery_point_update_package_for_cost_recalculation( $rates, $package ) {
1761 $deliveryPoint = WC()->session->get( 'mbe_delivery_point' ) ?? null;
1762 if ( ! empty( $deliveryPoint ) ) {
1763 $rateTaxes = $rates[WC()->session->get( 'chosen_shipping_methods' )[0]]->get_taxes();
1764 if ( wc_tax_enabled() && WC()->cart->display_prices_including_tax() && ! empty( $rateTaxes ) && ( WC()->session->get( 'mbe_delivery_point_update' ) ?? false ) ) {
1765 $logger = new Mbe_Shipping_Helper_Logger();
1766 $logger->logVar( $deliveryPoint, 'Delivery Point recalculation - removing taxes from map cost' );
1767 $deliveryPoint->cost = $this->helper->round( $this->helper->calculateNetPriceFromGross( $deliveryPoint->cost, $this->getShippingTaxPercentageFromCart($rateTaxes) ) );
1768 $logger->logVar( $deliveryPoint, 'Delivery Point recalculation - taxes removed from map cost' );
1769 WC()->session->set( 'mbe_delivery_point', $deliveryPoint );
1770 WC()->session->set( 'mbe_delivery_point_update', null );
1771 WC()->session->set( 'mbe_delivery_point_markup', $this->helper->getHandlingFee() );
1772 }
1773
1774 // Always check if the markup / handling fee has been changed (valid only in the same session) and update the delivery point cost and the session option
1775 if ( $this->helper->getHandlingFee() !== WC()->session->get( 'mbe_delivery_point_markup' ) ) {
1776 $deliveryPoint->cost = $deliveryPoint->cost - WC()->session->get( 'mbe_delivery_point_markup' ) + $this->helper->getHandlingFee();
1777 WC()->session->set( 'mbe_delivery_point', $deliveryPoint );
1778 WC()->session->set( 'mbe_delivery_point_markup', $this->helper->getHandlingFee() );
1779 }
1780
1781 $package['delivery_point'] = $deliveryPoint;
1782
1783 }
1784
1785 return $rates;
1786 }
1787
1788 function wf_mbe_delivery_point_set_meta_field_review( $data ) {
1789 $logger = new Mbe_Shipping_Helper_Logger();
1790 WC()->session->set( 'mbe_delivery_point', null );
1791 $postData = array();
1792 parse_str( $data, $postData );
1793 $deliveryPoint = json_decode( $postData['gel-proximity-selection'] ?? '' );
1794 $deliveryPointUpdate = json_decode( $postData['gel-proximity-selection-update'] ?? false );
1795
1796 if ( ! empty( $deliveryPoint ) && $this->isDeliveryPointServiceMethod( $postData['shipping_method'] ) ) {
1797 $logger->logVar( $deliveryPoint, 'Delivery point selection, refresh rates' );
1798 WC()->session->set( 'mbe_delivery_point', $deliveryPoint );
1799 WC()->session->set( 'mbe_delivery_point_update', $deliveryPointUpdate );
1800 }
1801
1802 // Check if the session variable is empty due to a json_decode() error and log an error
1803 if ( ! empty( $postData['gel-proximity-selection'] ) && empty( $deliveryPoint ) ) {
1804 $message = __( 'Possible issue with delivery point content/escaping. This delivery point cannot be correctly selected' );
1805 $logger->logVar( $postData['gel-proximity-selection'], $message );
1806 WC()->session->set( 'mbe_delivery_point', null ); // remove the delivery point to be sure it's not retaining an old value
1807 wc_add_notice( $message, 'error' );
1808 }
1809 }
1810
1811 function wf_mbe_delivery_point_set_shipping_address( $data ) {
1812 $logger = new Mbe_Shipping_Helper_Logger();
1813 // convert $data['shipping_method'] to array to avoid issues with empty (virtual products) or string values
1814 $shippingMethod = is_array( $data['shipping_method'] ) ? $data['shipping_method'] : [ $data['shipping_method'] ];
1815 $serviceOK = $this->isDeliveryPointServiceMethod( $shippingMethod );
1816 $logger->logVar( $shippingMethod, 'wf_mbe_wooCommerce_shipping_uap_address - Shipping Method' );
1817 if ( ! empty( $_POST['gel-proximity-selection'] ) && $serviceOK ) {
1818 $deliveryPointAddress = json_decode( stripslashes( $_POST['gel-proximity-selection'] ) );
1819 $logger->logVar( $deliveryPointAddress->code, 'wf_mbe_gel_delivery_point_set_shipping_address - GEL PUDO' );
1820 // Set the Delivery Point address as shipping address
1821 // $_POST['mbe_delivery_point_data'] = sanitize_text_field( $deliveryPointAddress->pickupPointId );
1822 $mbeDeliveryPointData = wp_json_encode( $deliveryPointAddress );
1823 $data['mbe_delivery_point_data'] = $mbeDeliveryPointData !== false ? $mbeDeliveryPointData : ''; // encode to json again to run some sanitization
1824 $data['shipping_company'] = sanitize_text_field( $deliveryPointAddress->description );
1825 $data['shipping_address_1'] = sanitize_text_field( $deliveryPointAddress->address );
1826 $data['shipping_postcode'] = sanitize_text_field( $deliveryPointAddress->zipCode );
1827 $data['shipping_city'] = sanitize_text_field( $deliveryPointAddress->city );
1828 $data['shipping_country'] = sanitize_text_field( $deliveryPointAddress->country );
1829 $data['shipping_state'] = array_search( ucfirst( strtolower( sanitize_text_field( $deliveryPointAddress->city ) ) ), WC()->countries->get_states( sanitize_text_field( $deliveryPointAddress->country ) ) );
1830 }
1831
1832 return $data;
1833 }
1834
1835 /**
1836 * Remove the delivery point session variable
1837 *
1838 * This method removes the custom WC_Session variable 'mbe_delivery_point' that is used to store
1839 * the selected delivery point during checkout process.
1840 *
1841 * @return void
1842 */
1843 function wf_mbe_remove_delivery_point_session_variable() {
1844 // Remove the custom WC_Session variable
1845 WC()->session->set( 'mbe_delivery_point', null );
1846 }
1847
1848 function wf_mbe_wooCommerce_shipping_custom_mapping_meta_field( $order_id ) {
1849 if ( $this->helper->isMbeShippingCustomMapping( $this->helper->getShippingMethod( wc_get_order( $order_id ) ) ) ) {
1850 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
1851 $order = wc_get_order( $order_id );
1852 $order->update_meta_data( Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_CUSTOM_MAPPING, 'yes' );
1853 $order->save();
1854 } else {
1855 update_post_meta( $order_id, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_CUSTOM_MAPPING, 'yes' );
1856 }
1857 }
1858 }
1859
1860 function wf_mbe_wooCommerce_shipping_custom_mapping_meta_field_checkout_block( WC_Order $order ) {
1861 if ( $this->helper->isMbeShippingCustomMapping( $this->helper->getShippingMethod( $order ) ) ) {
1862 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
1863 $order->update_meta_data( Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_CUSTOM_MAPPING, 'yes' );
1864 $order->save();
1865 } else {
1866 update_post_meta( $order->get_id(), Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_CUSTOM_MAPPING, 'yes' );
1867 }
1868 }
1869 }
1870
1871
1872 function mbe_woocommerce_email_track_id( $order, $sent_to_admin, $plain_text, $email ) {
1873 $mailArray = [ 'customer_invoice', 'customer_completed_order' ];
1874 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
1875 $trackingUrl = $order === false? '' : $order->get_meta( Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL );
1876 } else {
1877 $trackingUrl = get_post_meta( $order->get_id(), Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_URL, true );
1878 }
1879
1880 $trackId = $this->helper->getTrackingsString( $order->get_id() );
1881 if ( ! empty( $trackId ) && in_array( $email->id, $mailArray ) && $this->helper->getTrackingSetting() ) {
1882 echo '<table id="track_id" style="width: 100%; vertical-align: top; margin-bottom: 40px; padding: 0px; border:0px; border-spacing: 0; border-collapse: collapse;">
1883 <tbody>
1884 <tr>
1885 <td style="vertical-align: top; width: 40%; text-align: left; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif; border: 0; padding: 0;">
1886 <h2 style="color: #96588a; display: block; font-family: &quot;Helvetica Neue&quot;, Helvetica, Roboto, Arial, sans-serif; font-size: 18px; font-weight: bold; line-height: 130%; margin: 0 0 18px; text-align: left;"> ' . esc_html__( woocommerce_mbe_tracking_admin::TRACKING_TITLE_DISPLAY, 'mail-boxes-etc' ) . ' </h2>
1887 </td>
1888 </tr>
1889 <tr>
1890 <td style="vertical-align: top; width: 40%; text-align: left; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif; border: 0; padding: 0;">
1891 <strong>' . esc_html__( 'Tracking id: ', 'mail-boxes-etc' ) . '</strong>
1892 </td>
1893 <td style="vertical-align: top; width: 40%; text-align: left; font-family: \'Helvetica Neue\', Helvetica, Roboto, Arial, sans-serif; border: 0; padding: 0;">
1894 <a href="' . esc_url_raw( $trackingUrl . $trackId ) . '">
1895 ' . esc_html( $trackId ) . '
1896 </a>
1897 </td>
1898 </tr>
1899 </tbody>
1900 </table>';
1901 }
1902 }
1903
1904 function mbe_add_query_vars( $vars ) {
1905 $vars[] = "mbe_filetype";
1906
1907 return $vars;
1908 }
1909
1910 public function mbe_download_standard_package_file() {
1911 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_standard_package_file' ) ) {
1912 $fileType = sanitize_text_field( $_GET['mbe_filetype'] );
1913
1914 switch ( $fileType ) {
1915 case 'package':
1916 $this->helper->mbe_download_file( $this->helper->getCurrentCsvPackagesDir() );
1917 break;
1918 case 'package-template':
1919 $this->helper->mbe_download_file( $this->helper->getCsvTemplatePackagesDir() );
1920 break;
1921 case 'package-product':
1922 $this->helper->mbe_download_file( $this->helper->getCurrentCsvPackagesProductDir() );
1923 break;
1924 case 'package-product-template':
1925 $this->helper->mbe_download_file( $this->helper->getCsvTemplatePackagesProductDir() );
1926 break;
1927 default:
1928 break;
1929 }
1930 }
1931 }
1932
1933 public function mbe_download_shipping_file() {
1934 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_shipping_file' ) ) {
1935 $fileType = sanitize_text_field( $_GET['mbe_filetype'] );
1936
1937 switch ( $fileType ) {
1938 case 'shipping':
1939 $this->helper->mbe_download_file( $this->helper->getShipmentsCsvFileDir() );
1940 break;
1941 case 'shipping-template':
1942 $this->helper->mbe_download_file( $this->helper->getShipmentsCsvTemplateFileDir() );
1943 break;
1944 default:
1945 break;
1946 }
1947 }
1948 }
1949
1950 public function mbe_download_log_files() {
1951 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_log_files' ) ) {
1952 $zipfilepath = trailingslashit( $this->helper->getMbeLogDir() ) . 'log.zip';
1953 $wslogfilepath = $this->helper->getLogWsPath();
1954 $pluginfilepath = $this->helper->getLogPluginPath();
1955 $logZip = new \ZipArchive();
1956 if ( $logZip->open( $zipfilepath, \ZipArchive::CREATE | \ZipArchive::OVERWRITE ) === true ) {
1957 $logZip->addFile( $wslogfilepath, substr( $wslogfilepath, strrpos( $wslogfilepath, '/' ) + 1 ) );
1958 $logZip->addFile( $pluginfilepath, substr( $pluginfilepath, strrpos( $pluginfilepath, '/' ) + 1 ) );
1959 if ( $logZip->count() > 0 && $logZip->close() ) {
1960 $this->helper->mbe_download_file( $zipfilepath, 'mbe_log.zip', 'application/zip', true );
1961 }
1962 }
1963 $logZip = null;
1964 error_log( __( 'MBE Download log - files not found' ) );
1965 }
1966 exit;
1967 }
1968
1969
1970 public function mbe_delete_log_files() {
1971 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_delete_log_files' ) ) {
1972 try {
1973 $wslogfilepath = $this->helper->getLogWsPath();
1974 $pluginfilepath = $this->helper->getLogPluginPath();
1975 if ( file_exists( $wslogfilepath ) ) {
1976 wp_delete_file( $wslogfilepath );
1977 }
1978 if ( file_exists( $pluginfilepath ) ) {
1979 wp_delete_file( $pluginfilepath );
1980 }
1981 } catch ( \Exception $e ) {
1982 error_log( __( 'MBE Delete log - Unexpected error' ) . ' - ' . $e->getMessage() );
1983 }
1984 }
1985 wp_redirect( wp_get_referer() );
1986 }
1987
1988
1989 public function mbe_goto_advanced_login() {
1990 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_goto_advanced_login' ) ) {
1991 $this->helper->setLoginMode( false );
1992 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_LOGIN_LINK_ADV, true );
1993 }
1994 wp_redirect( wp_get_referer() );
1995 }
1996
1997 public function mbe_sign_in() {
1998 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_sign_in' ) ) {
1999 $mbeUser = $_GET[ MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_MBE_USERNAME ];
2000 $mbePwd = $_GET[ MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_MBE_PASSWORD ];
2001 $mbeCountry = $_GET[ MBE_ESHIP_ID . '_' . Mbe_Shipping_Helper_Data::XML_PATH_COUNTRY ];
2002 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_LOGIN_LINK_ADV, false );
2003
2004 if ( ! empty( $mbePwd ) && ! empty( $mbeUser ) ) {
2005 // Set the option in case it wasn't saved before
2006 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_MBE_USERNAME, hash('sha256', $mbeUser) );
2007 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_MBE_PASSWORD, password_hash($mbePwd, PASSWORD_DEFAULT) );
2008 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_COUNTRY, $mbeCountry );
2009 $this->helper->setWsUrl( $mbeCountry );
2010
2011 if ( $this->mbe_generate_api_key($mbeUser, $mbePwd) ) {
2012 // set advanced
2013 $this->helper->setLoginMode( false );
2014 update_option( 'mbe_shipping_admin_messages', [
2015 'message' => urlencode( __( 'Logged in', 'mail-boxes-etc' ) ),
2016 'status' => urlencode( 'success' )
2017 ] );
2018 } else {
2019 update_option( 'mbe_shipping_admin_messages', [
2020 'message' => urlencode( __( 'Error Logging in. Please enable debug and check the log files for more details', 'mail-boxes-etc' ) ),
2021 'status' => urlencode( 'error' )
2022 ] );
2023 }
2024 } else {
2025 update_option( 'mbe_shipping_admin_messages', [
2026 'message' => urlencode( __( 'Missing MBE Online Login Information', 'mail-boxes-etc' ) ),
2027 'status' => urlencode( 'error' )
2028 ] );
2029 }
2030 }
2031
2032 wp_redirect( wp_get_referer() );
2033 }
2034
2035 public function mbe_reset_login() {
2036 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_reset_login' ) ) {
2037 $logger = new Mbe_Shipping_Helper_Logger();
2038
2039 $this->helper->setLoginMode();
2040 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_WS_USERNAME, '' );
2041 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_WS_PASSWORD, '' );
2042 $this->helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_WS_URL, '' );
2043
2044 // delete the api key so it will be regenerated by the control hooked on plugin save
2045 $user_id = username_exists( MBE_WC_REST_API_USERNAME );
2046 if ( $user_id && email_exists( MBE_WC_REST_API_USER_EMAIL ) ) {
2047 $logger->log( 'Reset login - Delete Api Key' );
2048 $this->helper->removeMbeRestApiKey( $user_id );
2049 }
2050 }
2051 wp_redirect( wp_get_referer() );
2052 }
2053
2054 public function mbe_generate_api_key($mbeUser, $mbePwd) {
2055 $logger = new Mbe_Shipping_Helper_Logger();
2056 $logger->log( 'MBE Generate API KEY - Start' );
2057 $status = 'success';
2058 try {
2059 $ws = new MbeWs( true );
2060 $response = $ws->generateApiKey( $mbeUser, $mbePwd );
2061 if ( ! empty( $response ) ) {
2062 $this->helper->setWsUsername( $response->apiKey );
2063 $this->helper->setWsPassword( $response->apiSecret );
2064 $logger->log( 'MBE Generate API KEY - Done' );
2065 $message = __( 'eShip credentials generated correctly', 'mail-boxes-etc' );
2066 } else {
2067 $logger->log( 'MBE Generate API KEY - Empty response' );
2068 $message = __( 'eShip credentials not generated - Empty response', 'mail-boxes-etc' );
2069 $status = 'error';
2070 }
2071
2072 } catch ( \Exception $e ) {
2073 $logger->log( __( 'MBE Generate API KEY' ) . ' - ' . $e->getMessage() );
2074 $message = __( 'eShip credentials not generated. Check the log files for more details', 'mail-boxes-etc' );
2075 $status = 'error';
2076 }
2077 update_option( 'mbe_shipping_admin_messages', [
2078 'message' => urlencode( $message ),
2079 'status' => urlencode( $status )
2080 ] );
2081
2082 if ( $status === 'success' ) {
2083 return true;
2084 } else {
2085 return false;
2086 }
2087 // wp_redirect(wp_get_referer());
2088
2089 }
2090
2091 public function mbe_shipping_admin_notices() {
2092 // Manage WC environment notification
2093 $apiKeyMessage = maybe_unserialize( get_option( 'mbe_shipping_admin_messages' ) );
2094 if ( ! empty( $apiKeyMessage ) ) {
2095 $messageStatus = urldecode( $apiKeyMessage['status'] );
2096 $messageText = urldecode( $apiKeyMessage['message'] );
2097 if ( $messageStatus === 'error' ) {
2098 WC_Admin_Settings::add_error( $messageText );
2099 } else {
2100 WC_Admin_Settings::add_message( $messageText );
2101 }
2102 }
2103 delete_option( 'mbe_shipping_admin_messages' );
2104 }
2105
2106 // Set the local pickup default data
2107 public function mbe_woocommerce_get_pickup_default_data() {
2108 $ws = new Mbe_Shipping_Model_Ws();
2109 // get MOL default data
2110 $pickupData = $ws->getPickupDefaultData();
2111 // set local default data
2112 $this->helper->setLocalPickupDefaultData( $pickupData );
2113 }
2114
2115 // Send the local pickup default data to MOL
2116 public function mbe_woocommerce_set_pickup_default_data() {
2117 $ws = new Mbe_Shipping_Model_Ws();
2118 $ws->setPickupDefaultData( $this->helper->getLocalPickupDefaultData() );
2119 }
2120
2121 public function mbe_download_pickup_manifest() {
2122 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_pickup_manifest' ) ) {
2123 $ws = new Mbe_Shipping_Model_Ws();
2124 $logger = new Mbe_Shipping_Helper_Logger();
2125 try {
2126 $postId = sanitize_text_field( $_REQUEST['mbe_pickup_postid'] );
2127
2128 if ( ! $this->helper->isPickupShipped( $postId ) ) {
2129 throw new \MbeExceptions\ValidationException( __( 'Please select only pickup batches', 'mail-boxes-etc' ) );
2130 }
2131
2132 if ( ! $this->helper->hasTracking( $postId ) ) {
2133 throw new \MbeExceptions\ValidationException( sprintf( __( 'Order %s does not have a tracking number', 'mail-boxes-etc' ), $postId ) );
2134 }
2135
2136 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
2137 $order = wc_get_order( $postId );
2138 $masterTrackingNumber = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER);
2139 } else {
2140 $masterTrackingNumber = get_post_meta( $postId, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER, true );
2141 }
2142
2143 $response = $ws->getPickupManifest( $masterTrackingNumber );
2144
2145 $outputPdf = $response->Label->Stream;
2146 $outputPdfPath = $this->helper->mbeUploadDir() . DIRECTORY_SEPARATOR . current_datetime()->getTimestamp() . rand( 0, 999 ) . '.pdf';
2147
2148 if ( file_put_contents( $outputPdfPath, $outputPdf ) !== false ) {
2149 $this->helper->mbe_download_file( $outputPdfPath, "pickup_manifest_$postId.pdf", 'application/pdf', true );
2150 } else {
2151 $errMess = __( 'MBE Download pickup manifest - no document to download', 'mail-boxes-etc' );
2152 $this->helper->logErrorAndSetWpAdminMessage( $errMess, $logger );
2153 }
2154 } catch ( \MbeExceptions\ValidationException $e ) {
2155 $errMess = __( 'MBE Download pickup manifest - ' . $e->getMessage(), 'mail-boxes-etc' );
2156 $this->helper->logErrorAndSetWpAdminMessage( $errMess, $logger );
2157 } catch ( \Exception $e ) {
2158 $errMess = __( 'MBE Download pickup manifest - Unexpected error', 'mail-boxes-etc' ) . ' - ' . $e->getMessage();
2159 $this->helper->logErrorAndSetWpAdminMessage( $errMess, $logger );
2160 }
2161 }
2162 wp_redirect( wp_get_referer() );
2163 }
2164
2165 public function mbe_download_delivery_point_waybill() {
2166 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_download_delivery_point_waybill' ) ) {
2167 $ws = new Mbe_Shipping_Model_Ws();
2168 $logger = new Mbe_Shipping_Helper_Logger();
2169 try {
2170 $postId = sanitize_text_field( $_REQUEST['mbe_delivery_point_postid'] );
2171
2172 if ( ! $this->helper->isDeliveryPointOrder( $postId ) ) {
2173 throw new \MbeExceptions\ValidationException( __( 'Please select only delivery point orders', 'mail-boxes-etc' ) );
2174 }
2175
2176 if ( ! $this->helper->hasTracking( $postId ) ) {
2177 throw new \MbeExceptions\ValidationException( sprintf( __( 'Order %s does not have a tracking number', 'mail-boxes-etc' ), $postId ) );
2178 }
2179
2180 if ( \Automattic\WooCommerce\Utilities\OrderUtil::custom_orders_table_usage_is_enabled() ) {
2181 $order = wc_get_order( $postId );
2182 $masterTrackingNumber = $order===false?'':$order->get_meta(Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER);
2183 } else {
2184 $masterTrackingNumber = get_post_meta( $postId, Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_NUMBER, true );
2185 }
2186
2187 $response = $ws->getDeliveryPointShippingDocument( $masterTrackingNumber );
2188
2189 if ( $response !== false && empty( $response->Errors ) ) {
2190 $outputPdf = file_get_contents( $response->CourierWaybill ); // load the remote pdf
2191 $outputPdfPath = $this->helper->mbeUploadDir() . DIRECTORY_SEPARATOR . current_datetime()->getTimestamp() . rand( 0, 999 ) . '.pdf';
2192
2193 if ( file_put_contents( $outputPdfPath, $outputPdf ) !== false ) {
2194 $this->helper->mbe_download_file( $outputPdfPath, "delivery_point_waybill_$postId.pdf", 'application/pdf', true );
2195 } else {
2196 $errMsg = __( 'Download waybill - no document to download. Please, retry later', 'mail-boxes-etc' );
2197 $this->helper->logErrorAndSetWpAdminMessage( $errMsg, $logger );
2198 }
2199 } else {
2200 $errMsg = __( "Download waybill", 'mail-boxes-etc' ) . " $postId - " . __( $response->Errors->Error->Description ?? '', 'mail-boxes-etc' );
2201 $this->helper->logErrorAndSetWpAdminMessage( $errMsg, $logger );
2202 }
2203 } catch ( \MbeExceptions\ValidationException $e ) {
2204 $errMess = __( 'Download waybill - ' . $e->getMessage(), 'mail-boxes-etc' );
2205 $this->helper->logErrorAndSetWpAdminMessage( $errMess, $logger );
2206 } catch ( \MbeExceptions\ShippingDocumentException $e ) {
2207 $errMsg = sprintf( __( "Download waybill", 'mail-boxes-etc' ) . " - " . __( "%s", 'mail-boxes-etc' ), $e->getMessage() );
2208 $this->helper->logErrorAndSetWpAdminMessage( $errMsg, $logger );
2209 } catch ( \Exception $e ) {
2210 $errMess = __( 'MBE Download pickup manifest - Unexpected error', 'mail-boxes-etc' ) . ' - ' . $e->getMessage();
2211 $this->helper->logErrorAndSetWpAdminMessage( $errMess, $logger );
2212 }
2213 }
2214 wp_redirect( wp_get_referer() );
2215 }
2216
2217 public function mbe_eship_wp_notification() {
2218 // Manage WP environment notification
2219 $wpAdminMessages = maybe_unserialize( get_option( 'mbe_shipping_wp_admin_messages' ) ) ?: [];
2220 delete_option( 'mbe_shipping_wp_admin_messages' );
2221 $printf = '';
2222 foreach ( $wpAdminMessages as $adminMessage ) {
2223 $messageStatus = urldecode( $adminMessage['status'] ?? '' );
2224 $messageText = urldecode( $adminMessage['message'] );
2225 switch ( $messageStatus ) {
2226 case 'error':
2227 $printf .= printf( '<div class="notice notice-error is-dismissible"><p>' . esc_html__( 'Error' ) . ': %s</p></div>', esc_html( $messageText ) );
2228 break;
2229 case 'warning':
2230 $printf .= printf( '<div class="notice notice-warning is-dismissible"><p>%s</p></div>', esc_html( $messageText ) );
2231 break;
2232 default:
2233 $printf .= printf( '<div class="notice notice-info is-dismissible"><p>%s</p></div>', esc_html( $messageText ) );
2234 break;
2235 }
2236 }
2237
2238 return $printf;
2239 }
2240
2241 function csv_form_page_handler() {
2242 if ( isset( $_REQUEST['nonce'] ) && ( wp_verify_nonce( $_REQUEST['nonce'], 'csv_form_page_handler' ) || wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) ) {
2243
2244 global $wpdb;
2245
2246 $csvType = wc_clean( $_REQUEST['csv'] ) ?: null;
2247 $requestId = wc_clean( $_REQUEST['id'] ) ?: null;
2248 $csvFactory = new Mbe_Csv_Editor_Model_Factory();
2249 $csv = $csvFactory->create( $csvType );
2250 if ( ! empty( $csv ) ) {
2251 $message = '';
2252 $notice = '';
2253 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : 'woocommerce_mbe_csv_tabs&csv=' . $csvType . '&nonce=' . wp_create_nonce( 'woocommerce_mbe_csv_tabs' ) );
2254
2255 // default $item data to be used for new records
2256 $default = $csv->get_defaults();
2257
2258 $table_name = $csv->get_tablename();
2259
2260 // check post back and correct nonce
2261 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) {
2262 // combine default and request params
2263 $item = shortcode_atts( $default, $_REQUEST );
2264 // data validation
2265 $item_valid = $csv->validate_row( $item );
2266 try {
2267 if ( $item_valid === true ) {
2268 $ws = new Mbe_Shipping_Model_Ws();
2269 $result = true;
2270 if ( empty( $item[ $csv->get_ID() ] ) ) {
2271 do_action( MBE_ESHIP_ID . '_csv_editor_adding', $item );
2272 if ( ! $csv->get_isRemote() ) {
2273 $result = $wpdb->insert( $table_name, $item ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
2274 $item[ $csv->get_ID() ] = $wpdb->insert_id;
2275 } else {
2276 // Todo : check value online exist and = item - create a validateItem in class that extend Mbe_Shipping_Csv_Editor (eg.Mbe_Shipping_Csv_Editor_Pickup_Addresses)
2277 // set result = false if it fails
2278 }
2279 if ( $result !== false ) {
2280 $message = __( 'Item successfully saved', 'mail-boxes-etc' );
2281 do_action( MBE_ESHIP_ID . '_csv_editor_added', $item );
2282 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage . '&message=' . urlencode( $message ) ) ) );
2283 exit;
2284 } else {
2285 $notice = __( 'There was an error while saving the item', 'mail-boxes-etc' ) . ': ' . $wpdb->last_error;
2286 }
2287 } else {
2288 do_action( MBE_ESHIP_ID . '_csv_editor_updating', $item );
2289 if ( ! $csv->get_isRemote() ) {
2290 $result = $wpdb->update( $table_name, $item, array( 'id' => $item[ $csv->get_ID() ] ) ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
2291 } else {
2292 // Todo : check value online = item - create a validateItem in class that extend Mbe_Shipping_Csv_Editor (eg.Mbe_Shipping_Csv_Editor_Pickup_Addresses)
2293 // set result = false if it fails
2294 }
2295 if ( $result !== false ) {
2296 $message = __( 'Item successfully updated', 'mail-boxes-etc' );
2297 do_action( MBE_ESHIP_ID . '_csv_editor_updated', $item );
2298 wp_redirect( get_admin_url( get_current_blog_id(), 'admin.php?page=woocommerce_mbe_csv_tabs&csv=' . $csvType . '&message=' . urlencode( $message ) . '&nonce=' . wp_create_nonce( 'woocommerce_mbe_csv_tabs' ) ) );
2299 } else {
2300 $notice = __( 'There was an error while updating the item', 'mail-boxes-etc' ) . ': ' . $wpdb->last_error;
2301 }
2302 }
2303 } else {
2304 $notice = $item_valid;
2305 }
2306 } catch ( Exception $e ) {
2307 $notice = $e->getMessage();
2308 }
2309 } else {
2310 $item = $default;
2311 if ( isset( $requestId ) ) {
2312 if ( $csv->get_isRemote() ) {
2313 $item = $csv->get_remoteRow( $requestId );
2314 } else {
2315 $item = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM $table_name WHERE id = %d", $requestId ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
2316 }
2317 if ( ! $item ) {
2318 $item = $default;
2319 // $notice = __( 'Item not found', 'mail-boxes-etc' );
2320 }
2321 }
2322 }
2323
2324 // custom meta box is a method of $csv class
2325 add_meta_box( MBE_ESHIP_ID . '_csv_form_meta_box', $csv->get_title(),
2326 array( $csv, 'form_meta_box_handler' ),
2327 'csv-' . $csvType, 'normal', 'default' );
2328 ?>
2329
2330 <div class="wrap">
2331 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
2332 <h2><?php esc_html_e( 'Edit' ) . ' ' . $csv->get_title( false ) ?>
2333 <a class="add-new-h2"
2334 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
2335 <?php esc_html_e( 'Back to list', 'mail-boxes-etc' ) ?>
2336 </a>
2337 </h2>
2338
2339 <?php $this->mbe_eship_wp_notification() ?>
2340 <?php if ( ! empty( $notice ) ): ?>
2341 <div id="notice" class="notice notice-error is-dismissible">
2342 <p><?php echo wp_kses_post( $notice ) ?></p></div>
2343 <?php endif; ?>
2344 <?php if ( ! empty( $message ) ): ?>
2345 <div id="message" class="notice notice-success is-dismissible">
2346 <p><?php echo wp_kses_post( $message ) ?></p></div>
2347 <?php endif; ?>
2348
2349 <form id="form" method="POST">
2350 <input type="hidden" name="nonce"
2351 value="<?php esc_attr_e( wp_create_nonce( basename( __FILE__ ) ) ) ?>"/>
2352 <?php /* storing id to check if we need to add or update the item */ ?>
2353 <input type="hidden" name="id" value="<?php esc_attr_e( $item[ $csv->get_ID() ] ) ?>"/>
2354
2355 <div class="metabox-holder" id="poststuff">
2356 <div id="post-body">
2357 <div id="post-body-content">
2358 <?php /* render meta box */ ?>
2359 <?php do_meta_boxes( 'csv-' . $csvType, 'normal', $item ); ?>
2360 <input type="submit" value="<?php esc_attr_e( 'Save', 'mail-boxes-etc' ) ?>"
2361 id="submit"
2362 class="button-primary" name="submit">
2363 </div>
2364 </div>
2365 </div>
2366 </form>
2367 </div>
2368 <?php
2369 } else {
2370 ?>
2371 <div class="wrap">
2372 <h2><?php esc_html_e( 'Missing or wrong csv type', 'mail-boxes-etc' ) ?>
2373 <a class="add-new-h2"
2374 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?page=' . mbe_e_link_get_settings_url() . '&tab=' . MBE_ESHIP_ID . '&section=mbe_general' ) ); ?>">
2375 <?php esc_html_e( 'Back to settings', 'mail-boxes-etc' ) ?>
2376 </a>
2377 </h2>
2378 </div>
2379 <?php
2380 }
2381 } else {
2382 wp_redirect( wp_get_referer() );
2383 }
2384 }
2385
2386 public function pickup_data_form_page_handler() {
2387
2388 $pickupModel = new Mbe_Shipping_Model_Pickup_Custom_Data();
2389 $orderIds = isset( $_REQUEST['orderids'] ) ? json_decode( wc_clean( $_REQUEST['orderids'] ) ) : null;
2390 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2391 if ( ! empty( $orderIds )
2392 && isset( $_REQUEST['nonce'] )
2393 && (
2394 wp_verify_nonce( $_REQUEST['nonce'], 'mbe_edit_pickup' )
2395 || wp_verify_nonce( $_REQUEST['nonce'], 'mbe_pickup_return_from_address' )
2396 || wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) )
2397 )
2398 ) {
2399 $message = '';
2400 $notice = '';
2401 // $backPage = 'page=' . (isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE);
2402
2403 // default $item pickup data to be used for new records,
2404 // get local ones to avoid a call to the WS since very probably data will be verified and updated
2405 $default = $this->helper->getLocalPickupDefaultData();
2406
2407 // initialize the row id to be merged while editing an existing row
2408 $default['id'] = null;
2409
2410 // check Post back and correct nonce
2411 $requestId = wc_clean( $_REQUEST['id'] ?? null );
2412 if ( wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) {
2413 $default['date'] = '';
2414 $default['pickup_address_id'] = '';
2415 $default['pickup_batch_id'] = null;
2416
2417 $item = shortcode_atts( $default, $_REQUEST );
2418
2419 $item_valid = $pickupModel->validate_row( $item );
2420
2421 if ( $item_valid === true ) {
2422 // Save the custom pickup data
2423 $batchId = null;
2424 // If not updating
2425 if ( empty( $requestId ) ) {
2426 if ( count( $orderIds ) > 1 ) {
2427 $now = current_datetime();
2428 $batchId = $this->helper->getWsUsername() . '_' . $now->getTimestamp();
2429 $item['pickup_batch_id'] = $batchId;
2430 }
2431
2432 // Additional check to avoid creating a new custom data row if orders are already linked to pickup data
2433 $list = [];
2434 foreach ( $orderIds as $orderId ) {
2435 if ( ! empty( $this->helper->getOrderPickupBatchId( $orderId ) ) ) {
2436 $list[] = $orderId;
2437 }
2438 }
2439 if ( ! empty( $list ) ) {
2440 $errMess = sprintf( __( 'The orders %s are already linked to pickup data' ), implode( ',', $list ) );
2441 $this->helper->logErrorAndSetWpAdminMessage( $errMess );
2442 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
2443 exit;
2444 }
2445
2446 // Insert pickup custom data row
2447 $pickupCustomDataId = $pickupModel->insertRow( $item );
2448
2449 // Set order items meta fields
2450 foreach ( $orderIds as $orderId ) {
2451 // Additional check to avoid updating field for already existing shipments
2452 if ( ! $this->helper->hasTracking( $orderId ) ) {
2453 $this->helper->setOrderPickupCustomDataId( $orderId, $pickupCustomDataId );
2454 $this->helper->setOrderPickupBatchId( $orderId, $batchId );
2455 }
2456 }
2457 $action = 'created';
2458 } else {
2459 // Update the custom pickup data
2460 $pickupModel->updateRow( $item['id'], $item );
2461 $batchId = $item['pickup_batch_id'];
2462 $action = 'updated';
2463 }
2464 // Updating the backpage to the pickup batch list to show the newly created batch, but not if we have a single shipment
2465 // if(count($orderIds)>1) {
2466 $backPage = 'page=' . MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE;
2467 // }
2468
2469 if ( isset( $_REQUEST['submit_save'] ) ) {
2470 $this->helper->setWpAdminMessages( [
2471 'message' => urlencode( sprintf( __( 'The pickup %s has been %s', 'mail-boxes-etc' ), ( ! empty( $batchId ) ? 'batch ' . $batchId : '' ), __( $action, 'mail-boxes-etc' ) ) ),
2472 'status' => urlencode( 'success' )
2473 ] );
2474 } elseif ( isset( $_REQUEST['submit_savesend'] ) ) {
2475 $this->createPickup( $orderIds );
2476 }
2477 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
2478 exit;
2479 } else {
2480 $notice = $item_valid;
2481 }
2482 } else {
2483 $item = $default;
2484
2485 if ( isset( $requestId ) ) {
2486 $item = $pickupModel->getRow( $requestId );
2487 if ( ! $item ) {
2488 $item = $default;
2489 // $notice = __( 'Item not found', 'mail-boxes-etc' );
2490 }
2491 }
2492 }
2493
2494 $item['order_ids'] = is_array( $orderIds ) ? $orderIds : [ $orderIds ];
2495
2496 add_meta_box( MBE_ESHIP_ID . '_pickup_data_form_meta_box',
2497 ' ',
2498 array( $pickupModel, 'form_meta_box' ),
2499 'pickup-data-editor', 'normal', 'default'
2500 );
2501 ?>
2502 <div class="wrap">
2503 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
2504 <h2><?php esc_html_e( 'Pickup orders management', 'mail-boxes-etc' ) ?>
2505 <a class="add-new-h2"
2506 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
2507 <?php esc_html_e( 'Back to list', 'mail-boxes-etc' ) ?>
2508 </a>
2509 </h2>
2510
2511 <?php $this->mbe_eship_wp_notification() ?>
2512 <?php if ( ! empty( $notice ) ): ?>
2513 <div id="notice" class="notice notice-error is-dismissible">
2514 <p><?php echo wp_kses_post( $notice ) ?></p></div>
2515 <?php endif; ?>
2516 <?php if ( ! empty( $message ) ): ?>
2517 <div id="message" class="notice notice-success is-dismissible">
2518 <p><?php echo wp_kses_post( $message ) ?></p></div>
2519 <?php endif; ?>
2520 <form id="form" method="POST">
2521 <input type="hidden" name="nonce"
2522 value="<?php esc_attr_e( wp_create_nonce( basename( __FILE__ ) ) ) ?>"/>
2523 <input type="hidden" name="id" value="<?php esc_attr_e( $item['id'] ) ?>"
2524 <div class="metabox-holder" id="poststuff">
2525 <div id="post-body">
2526 <div id="post-body-content">
2527 <?php do_meta_boxes( 'pickup-data-editor', 'normal', $item ) ?>
2528 </div>
2529 </div>
2530 </div>
2531 </form>
2532 </div>
2533 <?php
2534 } else {
2535 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
2536 }
2537 }
2538
2539
2540 public function mbe_edit_pickup_data( $post_ids ) {
2541 if ( $this->helper->getPickupRequestEnabled() ) {
2542 switch ( $this->helper->getPickupRequestMode() ) {
2543 case Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_MANUAL :
2544 // Open default data editor and create a row for the batch ( pre-fill with default values from MOL ) and link it to the selected orders
2545 $backPage = '&backpage=' . urlencode( WOOCOMMERCE_MBE_TABS_PAGE );
2546 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . MBE_ESHIP_ID . '_pickup_data_tabs&orderids=' . urlencode( json_encode( $post_ids ) ) . $backPage . '&nonce=' . wp_create_nonce( 'mbe_edit_pickup' ) ) ) );
2547 break;
2548 case Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC :
2549 $this->createPickup( $post_ids );
2550 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . WOOCOMMERCE_MBE_TABS_PAGE ) ) );
2551 break;
2552 }
2553 }
2554 }
2555
2556
2557 public function mbe_delete_pickup_custom_data() {
2558 $logger = new \Mbe_Shipping_Helper_Logger();
2559 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_delete_pickup_custom_data' ) ) {
2560 global $wpdb;
2561 $id = wc_clean( $_REQUEST['id'] );
2562 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2563
2564 $pickupCustomData = new Mbe_Shipping_Model_Pickup_Custom_Data();
2565 $row = $pickupCustomData->getRow( $id );
2566
2567 // if ( 'ready' === strtolower( $row['status'] ) && isset( $row['pickup_batch_id'] ) ) {
2568 if ( 'ready' === strtolower( $row['status'] ) ) {
2569 // Detach all the order linked
2570 $selectOrderIds = $this->helper->select_pickup_orders_ids( $id );
2571 $orders = $wpdb->get_results( $selectOrderIds, ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
2572 $orderIds = array_map( 'absint', array_column( $orders, 'order_id' ) );
2573 $notDetached = [];
2574 foreach ( $orderIds as $orderId ) {
2575 if ( ! $this->helper->detachOrderFromPickupBatch( $orderId ) ) {
2576 $notDetached[] = $orderId;
2577 }
2578 }
2579 if ( empty( $notDetached ) ) {
2580 // Delete the custom data row
2581 $pickupCustomData->deleteRow( $id );
2582 } else {
2583 $message = sprintf( __( 'Cannot delete the pickup custom data row since order(s) %s cannot be detached as it seems to be a shipped pickup(s)', 'mail-boxes-etc' ), implode( ',', $notDetached ) );
2584 $this->helper->logErrorAndSetWpAdminMessage( $message, $logger );
2585 }
2586
2587 }
2588
2589 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
2590 }
2591 }
2592
2593 public function mbe_detach_order_from_batch() {
2594 $logger = new \Mbe_Shipping_Helper_Logger();
2595
2596 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_detach_order_from_batch' ) ) {
2597 $orderId = sanitize_text_field( $_REQUEST['mbe_pickup_postid'] );
2598 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2599 $pickupCustomDataId = $this->helper->getOrderPickupCustomDataId( $orderId );
2600
2601 if ( $this->helper->detachOrderFromPickupBatch( $orderId ) ) {
2602 do_action( MBE_ESHIP_ID . '_after_detach', $pickupCustomDataId );
2603 } else {
2604 $message = sprintf( __( 'Order %d cannot be detached as it is a shipped pickup', 'mail-boxes-etc' ), $orderId );
2605 $this->helper->logErrorAndSetWpAdminMessage( $message, $logger );
2606 }
2607 }
2608 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
2609 }
2610
2611 /**
2612 * Delete pickup batch if there are no items left
2613 *
2614 * @return void
2615 */
2616 // public function mbe_after_detach_check_pickup_batch_items($batchId) {
2617 // $pickupCustomData = new Mbe_Shipping_Model_Pickup_Custom_Data();
2618 //
2619 // if(empty($pickupCustomData->getBatchIdOrders($batchId))) {
2620 // $pickupCustomData->deleteRow( $pickupCustomData->getBatchIdRow($batchId)->id );
2621 // }
2622 // }
2623
2624 /**
2625 * Delete pickup if there are no items left
2626 *
2627 * @return void
2628 */
2629 public function mbe_after_detach_check_pickup_items( $pickupCustomDataId ) {
2630 $pickupCustomData = new Mbe_Shipping_Model_Pickup_Custom_Data();
2631
2632 if ( empty( $pickupCustomData->getPickupIdOrders( $pickupCustomDataId ) ) ) {
2633 $pickupCustomData->deleteRow( $pickupCustomDataId );
2634 }
2635 }
2636
2637
2638 public function mbe_send_pickup() {
2639 $logger = new \Mbe_Shipping_Helper_Logger();
2640 $logger->log( 'Send pickup Action - Start' );
2641 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2642 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_send_pickup' ) && isset( $_REQUEST['mbe_pickup_id'] ) && $this->helper->getPickupRequestEnabled() ) {
2643 $logger->log( 'Send pickup Action - Create pickup' );
2644 global $wpdb;
2645 $pickupCustomDataId = sanitize_text_field( $_REQUEST['mbe_pickup_id'] );
2646 $pickupCustomData = new Mbe_Shipping_Model_Pickup_Custom_Data();
2647 $hasPickupBatch = ! empty( $pickupCustomData->getRow( $pickupCustomDataId )['pickup_batch_id'] );
2648
2649 // $orders = $wpdb->get_results( $this->helper->select_pickup_batch_orders_ids( $pickupBatchId ), ARRAY_A );
2650 $orders = $wpdb->get_results( $this->helper->select_pickup_orders_ids( $pickupCustomDataId ), ARRAY_A ); // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching,WordPress.DB.DirectDatabaseQuery.SchemaChange
2651 $orderIds = array_map( 'absint', array_column( $orders, 'order_id' ) );
2652 $this->createPickup( $orderIds, $hasPickupBatch );
2653 }
2654 if ( ! $this->helper->getPickupRequestEnabled() ) {
2655 $message = __( 'Pickup request cannot be enabled, please check the settings', 'mail-boxes-etc' );
2656 $this->helper->logErrorAndSetWpAdminMessage( $message, $logger );
2657 }
2658 $logger->log( 'Send pickup Action - End' );
2659 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
2660 }
2661
2662 public function mbe_create_return_shipment() {
2663 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2664 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_create_return_shipment' ) && isset( $_REQUEST['mbe_post_id'] ) ) {
2665 $orderId = array_map( 'absint', (array) sanitize_text_field( $_REQUEST['mbe_post_id'] ) );
2666 $this->createReturnShipment( $orderId );
2667 }
2668 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
2669 }
2670
2671 public function mbe_woocommerce_get_advanced_return_address_data( $post_id ) {
2672 if ( $this->helper->canAdvancedReturn() ) {
2673 // Open the address data editor and create the return shipment
2674 $backPage = '&backpage=' . urlencode( WOOCOMMERCE_MBE_TABS_PAGE );
2675 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . MBE_ESHIP_ID . '_advanced_return_address_data_tabs&orderid=' . urlencode( $post_id ) . $backPage . '&nonce=' . wp_create_nonce( 'mbe_edit_advanced_return_address_data' ) ) ) );
2676 }
2677 }
2678
2679 public function advanced_return_address_data_form_page_handler() {
2680
2681 $orderId = isset( $_REQUEST['orderid'] ) ? wc_clean( $_REQUEST['orderid'] ) : null;
2682 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2683 if ( ! empty( $orderId )
2684 && isset( $_REQUEST['nonce'] )
2685 && (
2686 wp_verify_nonce( $_REQUEST['nonce'], 'mbe_edit_advanced_return_address_data' )
2687 || wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) // check nonce for post back (save)
2688 )
2689 ) {
2690 if ( wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) {
2691
2692 // Check Province field
2693 $senderProvince = sanitize_text_field( $_POST['sender_province'] );
2694 $receiverProvince = sanitize_text_field( $_POST['receiver_province'] );
2695 $senderProvinceIsEmptyForItaly = $this->helper->getCountry() === 'IT' && empty( $senderProvince );
2696 $senderProvinceIsNotTwoChar = $senderProvince && ! strlen( $senderProvince ) == 2;
2697 $receiverProvinceIsEmptyForItaly = $this->helper->getCountry() === 'IT' && empty( $receiverProvince );
2698 $receiverProvinceIsNotTwoChar = $receiverProvince && ! strlen( $receiverProvince ) == 2;
2699
2700 try {
2701
2702 if ( $senderProvinceIsEmptyForItaly || $receiverProvinceIsEmptyForItaly || $senderProvinceIsNotTwoChar || $receiverProvinceIsNotTwoChar ) {
2703 throw new Exception( __( "The field \"Province\" must not exceed 2 characters.", 'mail-boxes-etc' ) );
2704 }
2705
2706 $returnData =
2707 array(
2708 'sender_trade_name' => sanitize_text_field( $_POST['sender_trade_name'] ),
2709 'sender_address_1' => sanitize_text_field( $_POST['sender_address_1'] ),
2710 'sender_address_2' => sanitize_text_field( $_POST['sender_address_2'] ),
2711 'sender_address_3' => sanitize_text_field( $_POST['sender_address_3'] ),
2712 'sender_postcode' => sanitize_text_field( $_POST['sender_postcode'] ),
2713 'sender_city' => sanitize_text_field( $_POST['sender_city'] ),
2714 'sender_province' => $senderProvince,
2715 'sender_country' => sanitize_text_field( $_POST['sender_country'] ),
2716 'sender_reference' => sanitize_text_field( $_POST['sender_reference'] ),
2717 'sender_telephone_1' => sanitize_text_field( $_POST['sender_telephone_1'] ),
2718 'sender_telephone_2' => sanitize_text_field( $_POST['sender_telephone_2'] ),
2719 'sender_email_1' => sanitize_email( $_POST['sender_email_1'] ),
2720 'sender_email_2' => sanitize_email( $_POST['sender_email_2'] ),
2721 'sender_fax' => sanitize_text_field( $_POST['sender_fax'] ),
2722 'receiver_trade_name' => sanitize_text_field( $_POST['receiver_trade_name'] ),
2723 'receiver_address_1' => sanitize_text_field( $_POST['receiver_address_1'] ),
2724 'receiver_address_2' => sanitize_text_field( $_POST['receiver_address_2'] ),
2725 'receiver_address_3' => sanitize_text_field( $_POST['receiver_address_3'] ),
2726 'receiver_postcode' => sanitize_text_field( $_POST['receiver_postcode'] ),
2727 'receiver_city' => sanitize_text_field( $_POST['receiver_city'] ),
2728 'receiver_province' => $receiverProvince,
2729 'receiver_country' => sanitize_text_field( $_POST['receiver_country'] ),
2730 'receiver_reference' => sanitize_text_field( $_POST['receiver_reference'] ),
2731 'receiver_telephone_1' => sanitize_text_field( $_POST['receiver_telephone_1'] ),
2732 'receiver_telephone_2' => sanitize_text_field( $_POST['receiver_telephone_2'] ),
2733 'receiver_email_1' => sanitize_email( $_POST['receiver_email_1'] ),
2734 'receiver_email_2' => sanitize_email( $_POST['receiver_email_2'] ),
2735 'receiver_fax' => sanitize_text_field( $_POST['receiver_fax'] ),
2736 'pickup_date' => sanitize_text_field( $_POST['pickup_date'] ),
2737 'pickup_time_preferred_from' => sanitize_text_field( $_POST['pickup_time_preferred_from'] ),
2738 'pickup_time_preferred_to' => sanitize_text_field( $_POST['pickup_time_preferred_to'] ),
2739 'pickup_time_alternative_from' => sanitize_text_field( $_POST['pickup_time_alternative_from'] ),
2740 'pickup_time_alternative_to' => sanitize_text_field( $_POST['pickup_time_alternative_to'] ),
2741 'pickup_notes' => sanitize_text_field( $_POST['pickup_notes'] ),
2742 );
2743
2744
2745 $result = $this->createAdvancedReturnShipment( $orderId, $returnData );
2746 if ( $result ) {
2747 $this->helper->setWpAdminMessages( [ 'message' => __( 'Return shipment created' ) ] );
2748 }
2749
2750 } catch ( Exception $e ) {
2751 $this->helper->setWpAdminMessages( [
2752 'message' => __( 'Return shipment', 'mail-boxes-etc' ) . ' - ' . __( $e->getMessage(), 'mail-boxes-etc' ),
2753 'status' => 'error'
2754 ] );
2755 }
2756
2757 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
2758 exit;
2759 }
2760
2761 \Metaboxes\AdvancedReturnAddressData::add( MBE_ESHIP_ID . '_advanced_return_address_data_form_meta_box', 'advanced-return-address-data-meta-box' );
2762
2763 ?>
2764 <div class="wrap">
2765 <?php $this->mbe_eship_wp_notification() ?>
2766
2767 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
2768 <h2><?php esc_html_e( 'Return address data', 'mail-boxes-etc' ) ?>
2769 <a class="add-new-h2"
2770 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
2771 <?php esc_html_e( 'Back to list', 'mail-boxes-etc' ) ?>
2772 </a>
2773 </h2>
2774
2775 <form id="form" method="POST">
2776 <input type="hidden" name="nonce"
2777 value="<?php esc_attr_e( wp_create_nonce( basename( __FILE__ ) ) ) ?>"/>
2778 <!-- <input type="hidden" name="id" value="-->
2779 <?php //esc_attr_e($item['id']) ?><!--"-->
2780 <div class="metabox-holder" id="advanced-return-address-data-meta-box">
2781 <div id="post-body">
2782 <div id="post-body-content">
2783 <?php do_meta_boxes( 'advanced-return-address-data-meta-box', 'normal', $orderId ) ?>
2784
2785 <table style="width: 100%; margin-top: 20px;">
2786 <tbody>
2787 <tr>
2788 <td colspan="2">
2789 <div style="float:right;">
2790 <a class="button button-secondary"
2791 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
2792 <?php esc_html_e( 'Cancel', 'mail-boxes-etc' ) ?>
2793 </a>
2794 <input type="submit"
2795 value="<?php esc_attr_e( 'Save and send', 'mail-boxes-etc' ); ?>"
2796 class="button button-primary">
2797 </div>
2798 </td>
2799 </tr>
2800 </tbody>
2801 </table>
2802
2803 </div>
2804 </div>
2805 </div>
2806 </form>
2807 </div>
2808 <?php
2809 } else {
2810 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
2811 }
2812 }
2813
2814 public function mbe_after_delete_pickup_address_disable_pickup_if_no_default_address( $ids, $csvType ) {
2815 $logger = new \Mbe_Shipping_Helper_Logger();
2816 $helper = new Mbe_Shipping_Helper_Data();
2817 if ( 'pickup-addresses' === $csvType
2818 && ! $helper->hasDefaultPickupAddress()
2819 && $helper->getPickupRequestEnabled()
2820 && $helper->getPickupRequestMode() === Mbe_Shipping_Helper_Data::MBE_PICKUP_REQUEST_AUTOMATIC
2821 ) {
2822 $helper->setOption( Mbe_Shipping_Helper_Data::XML_PATH_PICKUP_REQUEST_ENABLED, 0 );
2823 $message = __( 'Pickup request cannot be enabled, please set a default pickup address', 'mail-boxes-etc' );
2824 $this->helper->logErrorAndSetWpAdminMessage( $message );
2825 $logger->log( 'Default pickup address missing, disabling pickup' );
2826 }
2827 }
2828
2829 function mbe_eship_check_tax_and_duties_default_options() {
2830 $helper = new Mbe_Shipping_Helper_Data();
2831 $logger = new Mbe_Shipping_Helper_Logger();
2832 // Check if Activation flag exists and if the default value setter didn't already run
2833 if ( ! $helper->hasOption( Mbe_Shipping_Helper_Data::XML_PATH_TAX_DUTIES_ENABLED ) && $helper->getPermissionEnabledTaxAndDuties() ) {
2834 update_option( MBE_SCHEMA_FLAG_OPTION, 'yes' );
2835 $logger->log( 'Updating schema flag to run default value setter for MBE Easy Duty' );
2836 }
2837 }
2838
2839 function mbe_eship_add_tax_and_duties_fee($data) {
2840 $selectedMethod = WC()->session->get('chosen_shipping_methods');
2841 WC()->session->set( 'mbe_tax_and_duties_show_info_text', '');
2842
2843 if ( $this->helper->isMBEShippingMethod( $selectedMethod ) ) {
2844 $rateData = $this->getRateData( $selectedMethod[0] );
2845
2846 $rateMetaData = [];
2847 if(!empty($rateData)) {
2848 $rateMetaData = $rateData->get_meta_data() ?? [];
2849
2850 if ( ! empty( $rateMetaData ) ) {
2851 $customDutyGuaranteed = $rateMetaData['tax_and_duties_data']['custom_duties_guaranteed'] ?? false;
2852
2853 if ( $customDutyGuaranteed && $this->helper->addTaxAndDutiesToTotal() ) {
2854 WC()->session->set( 'mbe_tax_and_duties_show_info_text', 'DDP' );
2855 } else {
2856 WC()->session->set( 'mbe_tax_and_duties_show_info_text', 'DAP' );
2857 }
2858 WC()->session->set( 'mbe_tax_and_duties_info_text_value', $rateMetaData['tax_and_duties_data']['net_tax_and_duty_total_price'] ?? 0 );
2859 }
2860 }
2861
2862 }
2863 }
2864
2865 function mbe_show_tax_and_duties_checkout_message() {
2866 if ($this->helper->isEnabledTaxAndDuties()) {
2867 // If the selected method is mbe and Tax&duty is not guaranteed or not DDP, show the message
2868 $taxAndDutiesDAP = WC()->session->get( 'mbe_tax_and_duties_show_info_text' ) ?? 'DAP';
2869 $taxAndDutiesValue = WC()->session->get( 'mbe_tax_and_duties_info_text_value' ) ?? null;
2870
2871 switch ( $taxAndDutiesDAP ) {
2872 case 'DAP':
2873 echo wp_kses_post( '<div style="font-size: 1rem; padding: 1rem; background: #eee;">
2874 ' . sprintf( __( 'As for all international shipments, customs requires a payment to clear goods through customs. It is a cost independent of our policies and tariffs. The <strong><span>%s</span></strong> figure shown may vary depending on the legislation of the country of destination.', 'mail-boxes-etc' ), wp_kses_post( wc_price( $taxAndDutiesValue ) ) ) . '
2875 </div>' );
2876 break;
2877 case 'DDP':
2878 echo wp_kses_post( '<div style="font-size: 1rem; padding: 1rem; background: #eee;">
2879 ' . sprintf( __( 'As with for all international shipments, customs requires a payment to clear goods through customs. It is a cost independent of our policies and tariffs, but the figure of <strong><span>%s</span></strong> charged ensures customs clearance, taken care of by us.', 'mail-boxes-etc' ), wp_kses_post( wc_price( $taxAndDutiesValue ) ) ) . '
2880 </div>' );
2881 break;
2882 default:
2883 break;
2884 }
2885 }
2886 }
2887
2888 function mbe_eship_check_tax_and_duties() {
2889 if ( $this->helper->mustDisableTaxAndDuties() && $this->helper->isEnabledTaxAndDuties() ) {
2890 $this->helper->setEnabledTaxAndDuties( 0 );
2891 $this->helper->logErrorAndSetWCAdminMessage( __( 'MBE Easy Duty cannot be enabled, please check the pickup mode and courier and services settings', 'mail-boxes-etc' ), new Mbe_Shipping_Helper_Logger() );
2892 }
2893 }
2894
2895 public function wf_mbe_wooCommerce_shipping_hide_custom_order_meta_keys( $formatted_meta, $thisa ) {
2896 foreach ( $formatted_meta as $key => $meta ) {
2897 if ( in_array( $meta->key, array(
2898 Mbe_Shipping_Helper_Data::META_FIELD_DELIVERY_POINT_CUSTOM_DATA,
2899 Mbe_Shipping_Helper_Data::META_FIELD_DELIVERY_POINT_SHIPMENT,
2900 Mbe_Shipping_Helper_Data::META_FIELD_PICKUP_CUSTOM_DATA_ID,
2901 Mbe_Shipping_Helper_Data::META_FIELD_IS_PICKUP_SHIPPING,
2902 Mbe_Shipping_Helper_Data::META_FIELD_METHOD_MBE_SERVICE_ID,
2903 Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_TRACKING_MBE_STATUS,
2904 Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_RETURN_TRACKING_MBE_STATUS,
2905 Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_RETURN_TRACKING_NUMBER,
2906 Mbe_Shipping_Helper_Data::SHIPMENT_SOURCE_DEPARTMENTS_ADDRESS,
2907 Mbe_Shipping_Helper_Data::META_FIELD_DYNAMIC_PACKAGE_DATA
2908 ) ) ) {
2909 unset( $formatted_meta[ $key ] );
2910 }
2911 }
2912
2913 return $formatted_meta;
2914 }
2915
2916 /**
2917 * @param array $shippingMethod
2918 *
2919 * @return bool
2920 */
2921 protected function isDeliveryPointServiceMethod( array $shippingMethod ): bool {
2922 $serviceOK = ! empty( preg_grep( '/^' . MBE_DELIVERY_POINT_SERVICE_METHOD . '/', $shippingMethod ) );
2923
2924 return $serviceOK;
2925 }
2926
2927 /**
2928 * @return array
2929 */
2930 protected function getShippingTaxPercentageFromCart($taxes = null): float {
2931 $taxPercentage = 0;
2932 $rateTaxes = !empty(WC()->cart->get_shipping_taxes()) ? WC()->cart->get_shipping_taxes() : $taxes;
2933 foreach ($rateTaxes as $key => $shipping_tax ) {
2934 $taxPercentage += WC_Tax::get_rate_percent_value( $key );
2935 }
2936
2937 return $taxPercentage;
2938 }
2939
2940 protected function getRateData( $chosen_method_id ) {
2941 $found_rate = null;
2942 $packages = WC()->cart->get_shipping_packages();
2943
2944 foreach ( $packages as $package_key => $package ) {
2945 $shipping_for_package = WC()->session->get( 'shipping_for_package_' . $package_key );
2946
2947 if ( ! empty( $shipping_for_package['rates'][ $chosen_method_id ] ) ) {
2948 $found_rate = $shipping_for_package['rates'][ $chosen_method_id ];
2949 break;
2950 }
2951 }
2952
2953 return $found_rate;
2954 }
2955
2956 public function mbe_edit_department_address_data( $post_ids ) {
2957 if ( $this->helper->canSelectDepartmentForOrders() ) {
2958 // Open default data editor and create a row for the batch ( pre-fill with default values from MOL ) and link it to the selected orders
2959 $backPage = '&backpage=' . urlencode( WOOCOMMERCE_MBE_TABS_PAGE );
2960 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . MBE_ESHIP_ID . '_department_address_data_tabs&orderids=' . urlencode( json_encode( $post_ids ) ) . $backPage . '&nonce=' . wp_create_nonce( 'mbe_select_department' ) ) ) );
2961 }
2962 }
2963
2964 public function department_address_data_form_page_handler() {
2965 $orderIds = isset( $_REQUEST['orderids'] ) ? json_decode( wc_clean( $_REQUEST['orderids'] ) ) : null;
2966 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
2967 if ( ! empty( $orderIds )
2968 && isset( $_REQUEST['nonce'] )
2969 && (
2970 wp_verify_nonce( $_REQUEST['nonce'], 'mbe_select_department' )
2971 || wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) // check nonce for post back (save)
2972 )
2973 ) {
2974 if ( wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) {
2975 $departmentAddressId = sanitize_key( $_REQUEST['department_address_id'] );
2976 $failed = [];
2977 foreach ( $orderIds as $order_id ) {
2978 // get the old values to check if it needs to be updated
2979 $oldValue = $this->helper->getOrderDepartmentAddressId( $order_id );
2980 if ( $oldValue !== $departmentAddressId ) {
2981 // Update order's meta data
2982 if ( ! $this->helper->setOrderDepartmentAddressId( $order_id, $departmentAddressId ) ) {
2983 $failed[] = $order_id;
2984 }
2985 }
2986 }
2987 if ( count( $failed ) > 0 ) {
2988 $notice = __( 'There was an error while updating the orders: ', 'mail-boxes-etc' ) . implode( ',', $failed );
2989 } else {
2990 $this->helper->setWpAdminMessages( [
2991 'message' => __( 'Department data associated', 'mail-boxes-etc' ),
2992 'status' => 'success'
2993 ] );
2994 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
2995 exit;
2996 }
2997 }
2998
2999 \Metaboxes\DepartmentAddressData::add( MBE_ESHIP_ID . '_department_address_data_form_meta_box', 'department-address-data-selection' );
3000
3001 ?>
3002
3003 <div class="wrap">
3004 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
3005 <h2><?php esc_html_e( 'Department address selection', 'mail-boxes-etc' ) ?>
3006 <a class="add-new-h2"
3007 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
3008 <?php esc_html_e( 'Back to list', 'mail-boxes-etc' ) ?>
3009 </a>
3010 </h2>
3011
3012 <?php $this->mbe_eship_wp_notification() ?>
3013 <?php if ( ! empty( $notice ) ): ?>
3014 <div id="notice" class="notice notice-error is-dismissible">
3015 <p><?php echo wp_kses_post( $notice ) ?></p></div>
3016 <?php endif; ?>
3017 <?php if ( ! empty( $message ) ): ?>
3018 <div id="message" class="notice notice-success is-dismissible">
3019 <p><?php echo wp_kses_post( $message ) ?></p></div>
3020 <?php endif; ?>
3021 <form id="form" method="POST">
3022 <input type="hidden" name="nonce"
3023 value="<?php esc_attr_e( wp_create_nonce( basename( __FILE__ ) ) ) ?>"/>
3024 <!-- <input type="hidden" name="id" value="-->
3025 <?php //esc_attr_e($item['id']) ?><!--"-->
3026 <div class="metabox-holder" id="department-address-data-selection">
3027 <div id="post-body">
3028 <div id="post-body-content">
3029 <?php do_meta_boxes( 'department-address-data-selection', 'normal', $orderIds ) ?>
3030
3031 <input type="submit" value="<?php esc_html_e( 'Save', 'mail-boxes-etc' ) ?>"
3032 id="submit_save"
3033 class="button-primary" name="submit_save">
3034 </div>
3035 </div>
3036 </div>
3037 </form>
3038 </div>
3039 <?php
3040 } else {
3041 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
3042 }
3043 }
3044
3045 public function mbe_select_department_address_pickup() {
3046 $backPage = '&backpage=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
3047 $post_ids = array( (int) sanitize_key( $_REQUEST['mbe_pickup_postid'] ) );
3048
3049 if ( isset( $_REQUEST['nonce'] ) && wp_verify_nonce( $_REQUEST['nonce'], 'mbe_select_department_address_pickup' ) && $this->helper->canSelectDepartmentForOrders() ) {
3050 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . MBE_ESHIP_ID . '_department_address_data_tabs&orderids=' . urlencode( json_encode( $post_ids ) ) . $backPage . '&nonce=' . wp_create_nonce( 'mbe_select_department' ) ) ) );
3051 exit;
3052 }
3053 wp_redirect( esc_url_raw( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ) );
3054 }
3055
3056
3057 public function mbe_edit_dynamic_packages_data($orderIds) {
3058 if ( $this->helper->canEditDynamicPackageData() ) {
3059 $backPage = '&backpage=' . urlencode( WOOCOMMERCE_MBE_TABS_PAGE );
3060 // Open the dynamic package data editor
3061 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . MBE_ESHIP_ID . '_dynamic_packages_data_tabs&orderids=' . urlencode( json_encode($orderIds) ) . $backPage . '&nonce=' . wp_create_nonce( 'mbe_edit_dynamic_packages_data' ) ) ) );
3062 } else {
3063 $this->helper->setWpAdminMessages( [
3064 'message' => __( 'Edit Packages', 'mail-boxes-etc' ) . ' - ' . __( 'not enabled', 'mail-boxes-etc' ),
3065 'status' => 'error'
3066 ] );
3067 wp_redirect( esc_url_raw( admin_url( 'admin.php?page=' . urlencode( WOOCOMMERCE_MBE_TABS_PAGE ) ) ) );
3068 exit;
3069 }
3070 }
3071
3072 public function mbe_dynamic_packages_data_form_page_handler() {
3073 $backPage = 'page=' . ( isset( $_REQUEST['backpage'] ) ? sanitize_text_field( $_REQUEST['backpage'] ) : MBE_ESHIP_ID . '_' . WOOCOMMERCE_MBE_TABS_PICKUP_PAGE );
3074 $orderIds = isset( $_REQUEST['orderids'] ) ? json_decode( wc_clean( $_REQUEST['orderids'] ) ) : null;
3075
3076 if ( ! empty( $orderIds )
3077 && isset( $_REQUEST['nonce'] )
3078 && (
3079 wp_verify_nonce( $_REQUEST['nonce'], 'mbe_edit_dynamic_packages_data' )
3080 || wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) // check nonce for post back (save)
3081 )
3082 ) {
3083
3084 if ( wp_verify_nonce( $_REQUEST['nonce'], basename( __FILE__ ) ) ) {
3085 $orderPackagesData = $_REQUEST['mbe_packages'] ?: null;
3086
3087 $failed = [];
3088 foreach ( $orderIds as $order_id ) {
3089 $this->helper->setOrderDynamicPackageData( $order_id, json_encode($orderPackagesData) );
3090 }
3091
3092 if ( count( $failed ) > 0 ) {
3093 $notice = __( 'There was an error while updating the orders: ', 'mail-boxes-etc' ) . implode( ',', $failed );
3094 } else {
3095 $this->helper->setWpAdminMessages( [
3096 'message' => __( 'Packages data associated to order ', 'mail-boxes-etc' ) . implode( ',', $orderIds ),
3097 'status' => 'success'
3098 ] );
3099 wp_redirect( esc_url_raw( admin_url( 'admin.php?' . $backPage ) ) );
3100 exit;
3101 }
3102 }
3103
3104 DynamicPackagesData::add( MBE_ESHIP_ID . '_dynamic_packages_data_form_meta_box', 'dynamic-packages-data-edit' );
3105
3106 ?>
3107
3108 <div class="wrap">
3109 <div class="icon32 icon32-posts-post" id="icon-edit"><br></div>
3110 <h2><?php esc_html_e( 'Dynamic packages edit', 'mail-boxes-etc' ) ?>
3111 <a class="add-new-h2"
3112 href="<?php echo esc_url( get_admin_url( get_current_blog_id(), 'admin.php?' . $backPage ) ); ?>">
3113 <?php esc_html_e( 'Back to list', 'mail-boxes-etc' ) ?>
3114 </a>
3115 </h2>
3116
3117 <?php $this->mbe_eship_wp_notification() ?>
3118 <?php if ( ! empty( $notice ) ): ?>
3119 <div id="notice" class="notice notice-error is-dismissible">
3120 <p><?php echo wp_kses_post( $notice ) ?></p></div>
3121 <?php endif; ?>
3122 <?php if ( ! empty( $message ) ): ?>
3123 <div id="message" class="notice notice-success is-dismissible">
3124 <p><?php echo wp_kses_post( $message ) ?></p></div>
3125 <?php endif; ?>
3126 </div>
3127 <form id="form" method="POST">
3128 <input type="hidden" name="nonce"
3129 value="<?php esc_attr_e( wp_create_nonce( basename( __FILE__ ) ) ) ?>"/>
3130 <!-- <input type="hidden" name="id" value="-->
3131 <?php //esc_attr_e($item['id']) ?><!--"-->
3132 <div class="metabox-holder" id="dynamic-packages-data-edit">
3133 <div id="post-body">
3134 <div id="post-body-content">
3135 <?php do_meta_boxes( 'dynamic-packages-data-edit', 'normal', $orderIds ) ?>
3136 </div>
3137 </div>
3138 </div>
3139 </form>
3140 <?php
3141
3142 }
3143
3144 }
3145
3146 }
3147 }
3148 new mbe_e_link_wooCommerce_shipping_setup();
3149
3150 }