PluginProbe
Order Tracking – WordPress Status Tracking Plugin / 3.2.2
Order Tracking – WordPress Status Tracking Plugin v3.2.2
3.5.4 3.5.3 3.5.2 3.5.1 3.5.0 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.3.0 3.3.1 3.3.10 3.3.11 3.3.12 3.3.13 3.3.14 3.3.15 All 235 releases
order-tracking / includes / Order.class.php

Order.class.php in Order Tracking – WordPress Status Tracking Plugin 3.2.2, at includes/Order.class.php

590 lines 18.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class to act as a wrapper for a single order
4 */
5
6 if ( !defined( 'ABSPATH' ) )
7 exit;
8
9 if ( !class_exists( 'ewdotpOrder' ) ) {
10 class ewdotpOrder {
11
12 // The database ID of the current order
13 public $id = 0;
14
15 // Stores all of the custom field values for an order
16 public $custom_fields = array();
17
18 // Stores all of the previous statuses for an order
19 public $status_history = array();
20
21 /**
22 * Load an order based on a specific database record
23 * @since 3.0.0
24 */
25 public function load_order( $db_order ) {
26 global $ewd_otp_controller;
27
28 $this->id = is_object( $db_order ) ? $db_order->Order_ID : 0;
29
30 $this->name = is_object( $db_order ) ? $db_order->Order_Name : '';
31 $this->number = is_object( $db_order ) ? $db_order->Order_Number : '';
32 $this->email = is_object( $db_order ) ? $db_order->Order_Email : '';
33
34 $this->status = is_object( $db_order ) ? $db_order->Order_Status : '';
35 $this->external_status = is_object( $db_order ) ? $db_order->Order_External_Status : '';
36 $this->location = is_object( $db_order ) ? $db_order->Order_Location : '';
37
38 $this->notes_public = is_object( $db_order ) ? $db_order->Order_Notes_Public : '';
39 $this->notes_private = is_object( $db_order ) ? $db_order->Order_Notes_Private : '';
40 $this->customer_notes = is_object( $db_order ) ? $db_order->Order_Customer_Notes : '';
41
42 $this->customer = is_object( $db_order ) ? $db_order->Customer_ID : 0;
43 $this->sales_rep = is_object( $db_order ) ? $db_order->Sales_Rep_ID : 0;
44 $this->woocommerce_id = is_object( $db_order ) ? $db_order->WooCommerce_ID : 0;
45 $this->zendesk_id = is_object( $db_order ) ? $db_order->Zendesk_ID : 0;
46
47 $this->status_updated = is_object( $db_order ) ? $db_order->Order_Status_Updated : '';
48 $this->status_updated_fmtd = $this->date_formatted( $this->status_updated );
49
50 $this->display = is_object( $db_order ) ? ( $db_order->Order_Display == 'Yes' ? true : false ) : false;
51
52 $this->payment_price = is_object( $db_order ) ? $db_order->Order_Payment_Price : 0;
53 $this->payment_completed = is_object( $db_order ) ? ( $db_order->Order_Payment_Completed == 'Yes' ? true : false ) : false;
54 $this->paypal_receipt_number = is_object( $db_order ) ? $db_order->Order_PayPal_Receipt_Number : '';
55
56 $this->views = is_object( $db_order ) ? $db_order->Order_View_Count : 0;
57
58 $this->tracking_link_clicked = is_object( $db_order ) ? ( $db_order->Order_Tracking_Link_Clicked == 'Yes' ? true : false ) : false;
59 $this->tracking_link_code = is_object( $db_order ) ? $db_order->Order_Tracking_Link_Code : '';
60
61 $custom_fields = $ewd_otp_controller->settings->get_order_custom_fields();
62
63 foreach ( $custom_fields as $custom_field ) {
64
65 $this->custom_fields[ $custom_field->id ] = $ewd_otp_controller->order_manager->get_field_value( $custom_field->id, $this->id );
66 }
67
68 $statuses = ewd_otp_decode_infinite_table_setting( $ewd_otp_controller->settings->get_setting( 'statuses' ) );
69
70 foreach ( $statuses as $status ) {
71
72 if ( $this->external_status == $status->status ) { $this->current_status = $status; }
73 }
74
75 $locations = ewd_otp_decode_infinite_table_setting( $ewd_otp_controller->settings->get_setting( 'locations' ) );
76
77 foreach ( $locations as $location ) {
78
79 if ( $this->location == $location->name ) { $this->current_location = $location; }
80 }
81 }
82
83 /**
84 * Loads an order based on its ID
85 * @since 3.0.0
86 */
87 public function load_order_from_id( $order_id ) {
88 global $ewd_otp_controller;
89
90 $db_order = $ewd_otp_controller->order_manager->get_order_from_id( $order_id );
91
92 $this->load_order( $db_order );
93 }
94
95 /**
96 * Loads an order based on its tracking number
97 * @since 3.0.0
98 */
99 public function load_order_from_tracking_number( $order_number ) {
100 global $ewd_otp_controller;
101
102 $db_order = $ewd_otp_controller->order_manager->get_order_from_tracking_number( $order_number );
103
104 $this->load_order( $db_order );
105 }
106
107 /**
108 * Returns the WordPress user ID for this order's sales rep
109 * @since 3.0.0
110 */
111 public function get_sales_rep_wp_id() {
112
113 if ( empty( $this->sales_rep ) ) { return 0; }
114
115 $sales_rep = new ewdotpSalesRep();
116
117 $sales_rep->load_sales_rep_from_id( $this->sales_rep );
118
119 return ! empty( $sales_rep->wp_id ) ? $sales_rep->wp_id : 0;
120 }
121
122 /**
123 * Loads an order's status history
124 * @since 3.0.0
125 */
126 public function load_order_status_history() {
127 global $ewd_otp_controller;
128
129 $this->status_history = array();
130
131 $db_status_history = $ewd_otp_controller->order_manager->get_order_status_history( $this->id );
132
133 foreach ( $db_status_history as $db_status ) {
134
135 $status_history_object = new stdClass();
136
137 $status_history_object->id = $db_status->Order_Status_ID;
138 $status_history_object->status = $db_status->Order_Status;
139 $status_history_object->location = $db_status->Order_Location;
140 $status_history_object->internal_status = $db_status->Order_Internal_Status;
141 $status_history_object->updated = $db_status->Order_Status_Created;
142 $status_history_object->updated_fmtd = $this->date_formatted( $status_history_object->updated );
143
144 $this->status_history[] = $status_history_object;
145 }
146 }
147
148 /**
149 * Verify that the submitted email matches the one belonging to the order
150 * @since 3.0.0
151 */
152 public function verify_order_email( $email_address ) {
153
154 if ( $email_address == $this->email ) { return true; }
155
156 return false;
157 }
158
159 /**
160 * Verify that the submitted user ID matches either the customer or sales rep for this order
161 * @since 3.0.15
162 */
163 public function verify_order_user( $user_id ) {
164 global $ewd_otp_controller;
165
166 if ( empty( $user_id ) ) { return false; }
167
168 if ( $this->customer == $ewd_otp_controller->customer_manager->get_customer_id_from_wp_id( $user_id ) ) { return true; }
169
170 if ( $this->sales_rep == $ewd_otp_controller->sales_rep_manager->get_sales_rep_id_from_wp_id( $user_id ) ) { return true; }
171
172 return false;
173 }
174
175 /**
176 * Validates a submitted order, and calls insert_order if validated
177 * @since 3.0.0
178 */
179 public function process_client_order_submission() {
180 global $ewd_otp_controller;
181
182 $this->validate_submission();
183 if ( $this->is_valid_submission() === false ) {
184 return false;
185 }
186
187 $this->insert_order();
188
189 if ( ! empty( $this->status ) ) { $this->insert_order_status(); }
190
191 do_action( 'ewd_otp_insert_customer_order', $this );
192
193 return true;
194 }
195
196 /**
197 * Validate submission data. Expects to find data in $_POST.
198 * @since 3.0.0
199 */
200 public function validate_submission() {
201 global $ewd_otp_controller;
202
203 $this->validation_errors = array();
204
205 // reCAPTCHA
206 if ( $ewd_otp_controller->settings->get_setting( 'use-captcha' ) == 'recaptcha' ) {
207
208 if ( ! isset( $_POST['g-recaptcha-response'] ) ) {
209
210 $this->validation_errors[] = array(
211 'field' => 'recaptcha',
212 'error_msg' => 'No reCAPTCHA code',
213 'message' => __( 'Please fill out the reCAPTCHA box before submitting.', 'order-tracking' ),
214 );
215
216 }
217 else {
218
219 $secret_key = $ewd_otp_controller->settings->get_setting( 'captcha-secret-key' );
220 $captcha = sanitize_text_field( $_POST['g-recaptcha-response'] );
221
222 $url = 'https://www.google.com/recaptcha/api/siteverify?secret=' . urlencode( $secret_key ) . '&response=' . urlencode( $captcha );
223 $json_response = file_get_contents( $url );
224 $response = json_decode( $json_response );
225
226 $reCaptcha_error = false;
227 if ( json_last_error() != JSON_ERROR_NONE ) {
228
229 $response = new stdClass();
230 $response->success = false;
231 $reCaptcha_error = true;
232
233 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
234
235 error_log( 'ORP reCAPTCHA error. Raw respose: ' . print_r( array( $json_response ), true ) );
236 }
237 }
238
239 if ( ! $response->success ) {
240
241 $message = __( 'Please fill out the reCAPTCHA box again and re-submit.', 'ultimate-reviews' );
242
243 if ( $reCaptcha_error ) {
244
245 $message .= __( 'If you encounter reCAPTCHA error multiple times, please contact us.', 'ultimate-reviews' );
246 }
247
248 $this->validation_errors[] = array(
249 'field' => 'recaptcha',
250 'error_msg' => 'Invalid reCAPTCHA code',
251 'message' => $message,
252 );
253 }
254 }
255 }
256
257 // Order Basics
258 $this->number = $ewd_otp_controller->settings->get_setting( 'customer-order-number-prefix' ) . ewd_random_string( 5 ) . $ewd_otp_controller->settings->get_setting( 'customer-order-number-suffix' );
259
260 $this->name = empty( $_POST['ewd_otp_order_name'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_order_name'] );
261 $this->email = empty( $_POST['ewd_otp_order_email'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_order_email'] );
262 $this->location = empty( $_POST['ewd_otp_location'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_location'] );
263 $this->customer_notes = empty( $_POST['ewd_otp_customer_notes'] ) ? '' : sanitize_textarea_field( $_POST['ewd_otp_customer_notes'] );
264
265 $this->external_status = $this->status = $ewd_otp_controller->settings->get_setting( 'default-customer-order-form-status' );
266 $this->display = true;
267
268 if ( empty( $this->status ) ) {
269
270 $statuses = ewd_otp_decode_infinite_table_setting( $ewd_otp_controller->settings->get_setting( 'statuses' ) );
271
272 $status = reset( $statuses );
273
274 $this->external_status = $this->status = $status->status;
275 }
276
277 // Customer
278 $user = wp_get_current_user();
279
280 if ( $user ) {
281
282 $this->customer = $ewd_otp_controller->customer_manager->get_customer_id_from_wp_id( $user->ID );
283 }
284 elseif ( function_exists( 'FEUP_User' ) ) {
285
286 $feup_user = new FEUP_User();
287
288 if ( $feup_user->Is_Logged_In() ) {
289
290 $this->customer = $ewd_otp_controller->customer_manager->get_customer_id_from_feup_id( $feup_user->Get_User_ID() );
291 }
292 }
293
294 if ( empty( $this->customer ) and ! empty( $this->email ) and $ewd_otp_controller->settings->get_setting( 'allow-assign-orders-to-customers' ) ) {
295
296 $this->customer = $ewd_otp_controller->customer_manager->get_customer_id_from_email( $this->email );
297 }
298
299 // Sales Rep
300 if ( ! empty( $this->customer ) ) {
301
302 $this->sales_rep = $ewd_otp_controller->customer_manager->get_customer_field( 'Sales_Rep_ID', $this->customer );
303 }
304
305 if ( empty( $this->sales_rep ) ){
306
307 $this->sales_rep = empty( $_POST['ewd_otp_sales_rep'] ) ? $ewd_otp_controller->settings->get_setting( 'default-sales-rep' ) : intval( $_POST['ewd_otp_sales_rep'] );
308 }
309
310 $custom_fields = $ewd_otp_controller->settings->get_order_custom_fields();
311
312 foreach ( $custom_fields as $custom_field ) {
313
314 $input_name = 'ewd_otp_custom_field_' . $custom_field->id;
315
316 if ( $custom_field->type == 'checkbox' ) { $this->custom_fields[ $custom_field->id ] = ( empty( $_POST[ $input_name ] ) or ! is_array( $_POST[ $input_name ] ) ) ? array() : sanitize_text_field( implode( ',', $_POST[ $input_name ] ) ); }
317 elseif ( $custom_field->type == 'textarea' ) { $this->custom_fields[ $custom_field->id ] = empty( $_POST[ $input_name ] ) ? false : sanitize_textarea_field( $_POST[ $input_name ] ); }
318 else { $this->custom_fields[ $custom_field->id ] = empty( $_POST[ $input_name ] ) ? false : sanitize_text_field( $_POST[ $input_name ] ); }
319 }
320
321 do_action( 'ewd_otp_validate_order_submission', $this );
322 }
323
324 /**
325 * Validates a submitted order, and calls insert_order if validated
326 * @since 3.0.0
327 */
328 public function process_admin_order_submission() {
329 global $ewd_otp_controller;
330
331 $this->validate_admin_submission();
332
333 if ( $this->is_valid_submission() === false ) {
334 return false;
335 }
336
337 if ( $this->id ) {
338
339 $this->update_order();
340
341 if ( $this->status != $ewd_otp_controller->order_manager->get_order_field( 'Order_Status', $this->id ) ) {
342
343 $this->insert_order_status();
344
345 do_action( 'ewd_otp_status_updated', $this );
346 }
347 }
348 else {
349
350 $this->insert_order();
351
352 $this->insert_order_status();
353
354 do_action( 'ewd_otp_admin_order_inserted', $this );
355 }
356
357 return true;
358 }
359
360 /**
361 * Validate submission data entered via the admin page
362 * @since 3.0.0
363 */
364 public function validate_admin_submission() {
365 global $ewd_otp_controller;
366
367 $this->validation_errors = array();
368
369 if ( ! isset( $_POST['ewd-otp-admin-nonce'] )
370 or ! wp_verify_nonce( $_POST['ewd-otp-admin-nonce'], 'ewd-otp-admin-nonce' )
371 ) {
372 $this->validation_errors[] = __( 'The request has been rejected because it does not appear to have come from this site.', 'order-tracking' );
373 }
374
375 // Order Data
376 $this->number = empty( $_POST['ewd_otp_number'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_number'] );
377 $this->name = empty( $_POST['ewd_otp_name'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_name'] );
378 $this->email = empty( $_POST['ewd_otp_email'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_email'] );
379
380 $this->status = $this->external_status = empty( $_POST['ewd_otp_status'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_status'] );
381 $this->location = empty( $_POST['ewd_otp_location'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_location'] );
382 $this->display = ( empty( $_POST['ewd_otp_display'] ) or $_POST['ewd_otp_display'] == 'no' ) ? false : true;
383
384 $statuses = ewd_otp_decode_infinite_table_setting( $ewd_otp_controller->settings->get_setting( 'statuses' ) );
385
386 // Overwrite the external status of the order if the new status is an internal one
387 foreach ( $statuses as $status ) {
388
389 if ( $this->status == $status->status and $status->internal == 'yes' ) {
390
391 $this->external_status = $ewd_otp_controller->order_manager->get_order_field( 'Order_External_Status', $this->id );
392 }
393 }
394
395 $this->notes_public = empty( $_POST['ewd_otp_public_notes'] ) ? '' : sanitize_textarea_field( $_POST['ewd_otp_public_notes'] );
396 $this->notes_private = empty( $_POST['ewd_otp_private_notes'] ) ? '' : sanitize_textarea_field( $_POST['ewd_otp_private_notes'] );
397 $this->customer_notes = empty( $_POST['ewd_otp_customer_notes'] ) ? '' : sanitize_textarea_field( $_POST['ewd_otp_customer_notes'] );
398
399 $this->customer = empty( $_POST['ewd_otp_customer'] ) ? 0 : sanitize_text_field( $_POST['ewd_otp_customer'] );
400 $this->sales_rep = empty( $_POST['ewd_otp_sales_rep'] ) ? 0 : sanitize_text_field( $_POST['ewd_otp_sales_rep'] );
401
402 $this->payment_price = empty( $_POST['ewd_otp_payment_price'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_payment_price'] );
403 $this->payment_completed = ( ! empty( $_POST['ewd_otp_payment_completed'] ) and $_POST['ewd_otp_payment_completed'] == 'yes' ) ? true : false;
404 $this->paypal_receipt_number = empty( $_POST['ewd_otp_paypal_receipt_number'] ) ? '' : sanitize_text_field( $_POST['ewd_otp_paypal_receipt_number'] );
405
406 $custom_fields = $ewd_otp_controller->settings->get_order_custom_fields();
407
408 foreach ( $custom_fields as $custom_field ) {
409
410 $input_name = 'ewd-otp-custom-field-' . $custom_field->id;
411
412 if ( $custom_field->type == 'checkbox' ) { $this->custom_fields[ $custom_field->id ] = ( empty( $_POST[ $input_name ] ) or ! is_array( $_POST[ $input_name ] ) ) ? '' : sanitize_text_field( implode( ',', $_POST[ $input_name ] ) ); }
413 elseif ( $custom_field->type == 'textarea' ) { $this->custom_fields[ $custom_field->id ] = empty( $_POST[ $input_name ] ) ? false : sanitize_textarea_field( $_POST[ $input_name ] ); }
414 elseif ( $custom_field->type == 'file' or $custom_field->type == 'image' ) { $this->custom_fields[ $custom_field->id ] = ! empty( $_FILES[ $input_name ]['name'] ) ? $this->handle_file_upload( $input_name ) : ( ! empty( $_POST[ $input_name ] ) ? sanitize_text_field( $_POST[ $input_name ] ) : '' ); }
415 else { $this->custom_fields[ $custom_field->id ] = empty( $_POST[ $input_name ] ) ? false : sanitize_text_field( $_POST[ $input_name ] ); }
416 }
417 }
418
419 /**
420 * Takes an input name, uploads the file from that input if it exists, returns the file URL
421 * @since 3.0.0
422 */
423 public function handle_file_upload( $input_name ) {
424
425 if ( ! function_exists( 'wp_handle_upload' ) ) {
426
427 require_once( ABSPATH . 'wp-admin/includes/file.php' );
428 }
429
430 $args = array(
431 'test_form' => false
432 );
433
434 $uploaded_file = wp_handle_upload( $_FILES[ $input_name ], $args );
435
436 if ( $uploaded_file && empty( $uploaded_file['error'] ) ) {
437
438 return $uploaded_file['url'];
439 }
440 else {
441
442 return false;
443 }
444 }
445
446 /**
447 * Check if submission is valid
448 * @since 3.0.0
449 */
450 public function is_valid_submission() {
451
452 if ( !count( $this->validation_errors ) ) {
453 return true;
454 }
455
456 return false;
457 }
458
459 /**
460 * Takes a status, correctly updates the orders status based on whether its an internal or external status
461 * @since 3.0.0
462 */
463 public function set_status( $new_status ) {
464 global $ewd_otp_controller;
465
466 $statuses = ewd_otp_decode_infinite_table_setting( $ewd_otp_controller->settings->get_setting( 'statuses' ) );
467
468 $internal_status = false;
469
470 foreach ( $statuses as $status ) {
471
472 if ( $status->status == $new_status and $status->internal == 'yes' ) { $internal_status = true; }
473 }
474
475 if ( ! $internal_status ) {
476
477 $this->external_status = $new_status;
478 }
479
480 $this->status = $new_status;
481
482 $this->update_order();
483
484 $this->insert_order_status();
485
486 if ( ! $internal_status ) {
487
488 do_action( 'ewd_otp_status_updated', $this );
489 }
490 }
491
492 /**
493 * Takes a tracking link code and updates the tracking code value in the database for this order
494 * @since 3.0.0
495 */
496 public function set_tracking_link_code( $tracking_code ) {
497
498 $this->tracking_link_code = $tracking_code;
499
500 $this->update_order();
501 }
502
503 /**
504 * Takes a tracking link code and verifies that it matches the one currently saved for the order
505 * @since 3.0.0
506 */
507 public function verify_tracking_link( $tracking_code ) {
508
509 return $this->tracking_link_code == $tracking_code ? true : false;
510 }
511
512 /**
513 * Update the tracking link clicked flag for this order
514 * @since 3.0.0
515 */
516 public function set_tracking_link_clicked() {
517
518 $this->tracking_link_clicked = true;
519
520 $this->update_order();
521 }
522
523 /**
524 * Increase the view count for this order
525 * @since 3.0.0
526 */
527 public function increase_view_count() {
528 global $ewd_otp_controller;
529
530 $ewd_otp_controller->order_manager->increase_order_views( $this->id );
531 }
532
533 /**
534 * Insert a new order into the database
535 * @since 3.0.0
536 */
537 public function insert_order() {
538 global $ewd_otp_controller;
539
540 $id = $ewd_otp_controller->order_manager->insert_order( $this );
541
542 $this->id = $id;
543 }
544
545 public function insert_order_status() {
546 global $ewd_otp_controller;
547
548 if ( ! $this->id ) { return; }
549
550 $this->status_updated = date( 'Y-m-d H:i:s' );
551
552 $ewd_otp_controller->order_manager->update_order_status( $this );
553 }
554
555 /**
556 * Update an order already in the database
557 * @since 3.0.0
558 */
559 public function update_order() {
560 global $ewd_otp_controller;
561
562 $ewd_otp_controller->order_manager->update_order( $this );
563
564 }
565
566 /**
567 * Returns the date/time formatted based on the use WP timezone settings and formats
568 * @since 3.0.0
569 */
570 public function date_formatted( $input ) {
571 global $ewd_otp_controller;
572
573 $output = $input;
574
575 if ( $ewd_otp_controller->settings->get_setting( 'use-wp-timezone' ) ) {
576
577 $wp_tz = wp_timezone();
578 $current_tz = new DateTime( $input, new DateTimeZone( date_default_timezone_get() ) );
579 $offset = $wp_tz->getOffset( $current_tz );
580
581 $output = date(
582 get_option( 'date_format' ).' '.get_option( 'time_format' ),
583 ( $current_tz->format( 'U' ) + $offset )
584 );
585 }
586
587 return $output;
588 }
589 }
590 }