PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / curds / class-lp-order-curd.php

class-lp-order-curd.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at inc/curds/class-lp-order-curd.php

635 lines 17.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Order_CURD
4 *
5 * @since 3.0.0
6 */
7
8 use LearnPress\Models\UserItems\UserCourseModel;
9
10 defined( 'ABSPATH' ) || exit();
11
12 class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
13
14 /**
15 * @var string
16 */
17 protected $_meta_type = 'post';
18
19 /**
20 * @var array
21 */
22 protected $_meta_keys = array();
23
24 /**
25 * @param LP_Order $order
26 *
27 * @return mixed
28 */
29 public function create( &$order ) {
30 if ( ! $order instanceof LP_Order ) {
31 return false;
32 }
33
34 //$order->set_order_date( time() );
35 $order->set_order_key( learn_press_generate_order_key() );
36 $status = $this->format_status_save_db( $order );
37 $lp_time = new LP_Datetime( time() );
38
39 $order_data = array(
40 'post_author' => get_current_user_id(),
41 'post_parent' => $order->get_parent_id(),
42 'post_type' => LP_ORDER_CPT,
43 'post_status' => $status,
44 'ping_status' => 'closed',
45 'post_title' => $order->get_title(),
46 'post_date' => $lp_time->toSql( true ),
47 'post_date_gmt' => $lp_time->toSql(),
48 'post_excerpt' => $order->get_customer_note(),
49 );
50
51 $order_data = apply_filters( 'learn-press/order/new-data', $order_data );
52
53 $id = wp_insert_post( $order_data, true );
54 if ( $id && ! is_wp_error( $id ) ) {
55 $order->set_id( $id );
56 // Update title oder when order is have just create.
57 wp_update_post(
58 array(
59 'ID' => $id,
60 'post_title' => learn_press_transaction_order_number( $id ),
61 )
62 );
63 $this->_updates( $order );
64 }
65
66 return $id;
67 }
68
69 /**
70 * Update order.
71 *
72 * @param LP_Order $order
73 *
74 * @return int
75 * @Todo tungnx - check method
76 */
77 public function update( &$order ) {
78 if ( ! $order instanceof LP_Order ) {
79 return false;
80 }
81
82 $post = get_post( $order->get_id() );
83 $status = $this->format_status_save_db( $order );
84 $post_data = array(
85 'post_status' => $status,
86 );
87
88 // For case edit Order on Backend.
89 if ( isset( $_POST['order-date'] ) ) {
90 // Data time submit edit order will is local time
91 $order_date = LP_Request::get_param( 'order-date' );
92 $order_hour = LP_Request::get_param( 'order-hour', '00' );
93 $order_min = LP_Request::get_param( 'order-minute', '00' );
94 $date_time_local = $order_date . ' ' . $order_hour . ':' . $order_min . ':00';
95
96 // Date GMT
97 $lpDateTimeLocal = new LP_Datetime( $date_time_local );
98 $date_time_gmt = $lpDateTimeLocal->to_gmt_string( $lpDateTimeLocal );
99 $post_data['post_date'] = $date_time_local;
100 $post_data['post_date_gmt'] = $date_time_gmt;
101 } elseif ( $post->post_status === 'auto-draft'
102 && $post->post_date_gmt === '0000-00-00 00:00:00' ) {
103 $date_time_gmt = get_gmt_from_date( $post->post_date );
104 $post_data['post_date_gmt'] = $date_time_gmt;
105 }
106
107 $post_data = apply_filters( 'learn-press/order/update-data', $post_data, $order->get_id() );
108
109 /**
110 * When updating this object, to prevent infinite loops, use $wpdb
111 * to update data, since wp_update_post spawns more calls to the
112 * save_post action.
113 *
114 * This ensures hooks are fired by either WP itself (admin screen save),
115 * or an update purely from CRUD.
116 */
117 if ( doing_action( 'save_post' ) ) {
118 $GLOBALS['wpdb']->update( $GLOBALS['wpdb']->posts, $post_data, array( 'ID' => $order->get_id() ) );
119 clean_post_cache( $order->get_id() );
120 } else {
121 wp_update_post( array_merge( array( 'ID' => $order->get_id() ), $post_data ) );
122 }
123 $this->_updates( $order );
124
125 return $order->get_id();
126 }
127
128 /**
129 * Format status of LP Order before save DB.
130 *
131 * @param LP_Order $lp_order
132 *
133 * @return string
134 */
135 private function format_status_save_db( LP_Order $lp_order ): string {
136 $status = ! empty( $lp_order->get_status() ) ? $lp_order->get_status() : LP_ORDER_PENDING;
137 if ( $status === LP_ORDER_TRASH || $status === 'auto-draft' ) {
138 return $status;
139 }
140
141 if ( ! preg_match( '/^lp-/', $status ) ) {
142 $status = 'lp-' . $status;
143 }
144
145 return $status;
146 }
147
148 /**
149 * @param LP_Order $order
150 */
151 public function _updates( &$order ) {
152 $this->update_post_meta( $order );
153 $order->update_meta();
154 }
155
156 /**
157 * @param LP_Order $order
158 */
159 public function update_post_meta( $order ) {
160 $meta_data = array(
161 '_order_currency' => $order->get_currency(),
162 '_prices_include_tax' => 'no',
163 '_user_id' => $order->get_user_id(),
164 '_order_subtotal' => $order->get_subtotal(),
165 '_order_total' => $order->get_total(),
166 '_order_key' => $order->get_order_key(),
167 '_payment_method' => $order->get_data( 'payment_method', '' ),
168 '_payment_method_title' => $order->get_payment_method_title(),
169 '_user_ip_address' => $order->get_user_ip_address(),
170 '_user_agent' => $order->get_user_agent(),
171 '_order_version' => '3.0.0',
172 '_created_via' => $order->get_created_via(),
173 );
174
175 $checkout_email = $order->get_checkout_email();
176 if ( $checkout_email ) {
177 $meta_data['_checkout_email'] = $checkout_email;
178 }
179
180 foreach ( $meta_data as $key => $value ) {
181 update_post_meta( $order->get_id(), $key, $value );
182 }
183 }
184
185 /**
186 * Read order's items
187 *
188 * @param LP_Order $order
189 *
190 * @return mixed
191 */
192 /*
193 old function - comment by tungnx
194 public function read_items( $order ) {
195 global $wpdb;
196 $screen = function_exists('get_current_screen')? get_current_screen():null;
197 $query = $wpdb->prepare( "
198 SELECT order_item_id as id, order_item_name as name
199 , oim.meta_value as `course_id`
200 # , oim2.meta_value as `quantity`
201 # , oim3.meta_value as `total`
202 FROM {$wpdb->learnpress_order_items} oi
203 INNER JOIN {$wpdb->learnpress_order_itemmeta} oim ON oi.order_item_id = oim.learnpress_order_item_id AND oim.meta_key='_course_id'
204 # INNER JOIN {$wpdb->learnpress_order_itemmeta} oim2 ON oi.order_item_id = oim2.learnpress_order_item_id AND oim2.meta_key='_quantity'
205 # INNER JOIN {$wpdb->learnpress_order_itemmeta} oim3 ON oi.order_item_id = oim3.learnpress_order_item_id AND oim3.meta_key='_total'
206 WHERE order_id = %d
207 ", $order->get_id() );
208
209 $_items = $wpdb->get_results( $query );
210 $items = array();
211 // Loop items
212 if ( $_items ) {
213 foreach ( $_items as $item ) {
214 $item = (array) $item;
215 $items[$item['id']] = $item;
216 if(!$screen || $screen->id !== 'edit-lp_order'){
217 $this->get_item_meta( $item );
218 }
219 if ( ! empty( $item['course_id'] ) ) {
220 $items[ $item['id'] ] = $item;
221 }
222 }
223 }
224
225 return $items;// apply_filters( 'learn_press_order_get_items', $items, $this );
226 } */
227
228 /**
229 * Get order's items
230 *
231 * @param LP_Order $order
232 *
233 * @return mixed
234 * @author tungnx
235 * Todo: review to rewrite.
236 */
237 public function read_items( $order ) {
238 $key = "order/{$order->get_id()}/{$order->get_status()}/items";
239 $items = LP_Cache::cache_load_first( 'get', $key );
240 if ( false !== $items ) {
241 return $items;
242 }
243
244 global $wpdb;
245
246 $table_order_items = $wpdb->learnpress_order_items;
247 $table_order_item_meta = $wpdb->learnpress_order_itemmeta;
248
249 $query = $wpdb->prepare(
250 "SELECT o_item.order_item_id, o_item.order_item_name, o_itemmeta.meta_value, o_itemmeta.meta_key
251 From $table_order_items as o_item
252 INNER JOIN $table_order_item_meta as o_itemmeta
253 ON o_item.order_item_id = o_itemmeta.learnpress_order_item_id
254 WHERE o_item.order_id = %d
255 LIMIT %d",
256 $order->get_id(),
257 4 * 50
258 );
259
260 // Todo: write query to function and call ajax load more
261 $order_item_metas = $wpdb->get_results( $query, OBJECT );
262
263 $items = array();
264
265 foreach ( $order_item_metas as $order_item_meta ) {
266 if ( ! array_key_exists( $order_item_meta->order_item_id, $items ) ) {
267 $items[ $order_item_meta->order_item_id ] = array();
268 $items[ $order_item_meta->order_item_id ]['id'] = $order_item_meta->order_item_id;
269 $items[ $order_item_meta->order_item_id ]['name'] = isset( $order_item_meta->order_item_name ) ? $order_item_meta->order_item_name : '';
270 }
271
272 switch ( $order_item_meta->meta_key ) {
273 case '_course_id':
274 $items[ $order_item_meta->order_item_id ]['course_id'] = $order_item_meta->meta_value;
275 break;
276 case '_quantity':
277 $items[ $order_item_meta->order_item_id ]['quantity'] = $order_item_meta->meta_value;
278 break;
279 case '_subtotal':
280 $items[ $order_item_meta->order_item_id ]['subtotal'] = $order_item_meta->meta_value;
281 break;
282 case '_total':
283 $items[ $order_item_meta->order_item_id ]['total'] = $order_item_meta->meta_value;
284 break;
285 default:
286 $items[ $order_item_meta->order_item_id ][ $order_item_meta->meta_key ] = $order_item_meta->meta_value;
287 }
288 }
289
290 LP_Cache::cache_load_first( 'set', $key, $items );
291
292 return $items; // apply_filters( 'learn_press_order_get_items', $items, $this );
293 }
294
295 /**
296 * Get order's items
297 *
298 * @param LP_Order $order
299 * @param array $filter
300 *
301 * @return mixed
302 * @author tungnx
303 */
304 public function read_items_filter( $order, $filter = array() ) {
305 global $wpdb;
306
307 $p = $filter['p'];
308 $limit = $filter['limit'] * 4; // 4 fields on 1 item
309 $offset = $p * $limit;
310
311 $table_order_items = $wpdb->learnpress_order_items;
312 $table_order_item_meta = $wpdb->learnpress_order_itemmeta;
313
314 $query = $wpdb->prepare(
315 "SELECT o_item.order_item_id, o_item.order_item_name, o_itemmeta.meta_value, o_itemmeta.meta_key
316 From $table_order_items as o_item
317 INNER JOIN $table_order_item_meta as o_itemmeta
318 ON o_item.order_item_id = o_itemmeta.learnpress_order_item_id
319 WHERE o_item.order_id = %d
320 LIMIT %d, %d",
321 $order->get_id(),
322 $offset,
323 $limit
324 );
325
326 // Todo: write query to function and call ajax load more
327 $order_item_metas = $wpdb->get_results( $query, OBJECT );
328
329 $items = array();
330
331 foreach ( $order_item_metas as $order_item_meta ) {
332 if ( ! array_key_exists( $order_item_meta->order_item_id, $items ) ) {
333 $items[ $order_item_meta->order_item_id ] = array();
334 $items[ $order_item_meta->order_item_id ]['id'] = $order_item_meta->order_item_id;
335 $items[ $order_item_meta->order_item_id ]['name'] = isset( $order_item_meta->order_item_name ) ? $order_item_meta->order_item_name : '';
336 }
337
338 switch ( $order_item_meta->meta_key ) {
339 case '_course_id':
340 $items[ $order_item_meta->order_item_id ]['course_id'] = $order_item_meta->meta_value;
341 break;
342 case '_quantity':
343 $items[ $order_item_meta->order_item_id ]['quantity'] = $order_item_meta->meta_value;
344 break;
345 case '_subtotal':
346 $items[ $order_item_meta->order_item_id ]['subtotal'] = $order_item_meta->meta_value;
347 break;
348 case '_total':
349 $items[ $order_item_meta->order_item_id ]['total'] = $order_item_meta->meta_value;
350 break;
351 default:
352 $items[ $order_item_meta->order_item_id ][ $order_item_meta->meta_key ] = $order_item_meta->meta_value;
353 }
354 }
355
356 return $items; // apply_filters( 'learn_press_order_get_items', $items, $this );
357 }
358
359 /*public function getTotalItem() {
360 }*/
361
362 /*public function get_item_meta( &$item ) {
363 $metas = get_metadata( 'learnpress_order_item', $item['id'] );
364 if ( $metas ) {
365 foreach ( $metas as $k => $v ) {
366 $item[ preg_replace( '!^_!', '', $k ) ] = LP_Helper::maybe_unserialize( $v[0] );
367 }
368 }
369 }*/
370
371 public function delete( &$object ) {
372 // TODO: Implement delete() method.
373 }
374
375 /**
376 * @param LP_Order $order
377 *
378 * @return LP_Order
379 * @deprecated 4.2.3.5
380 */
381 /*public function cln( $order ) {
382 _deprecated_function( __METHOD__, '4.2.3.5' );
383
384 $cloned = clone $order;
385
386 $cloned->set_id( 0 );
387 $cloned->save();
388
389 $meta_keys = array(
390 '_order_currency',
391 '_prices_include_tax',
392 '_user_ip_address',
393 '_user_agent',
394 '_order_subtotal',
395 '_order_total',
396 '_order_key',
397 '_payment_method',
398 '_payment_method_title',
399 '_order_version',
400 '_created_via',
401 );
402
403 foreach ( $meta_keys as $key ) {
404 update_post_meta( $cloned->get_id(), $key, get_post_meta( $order->get_id(), $key, true ) );
405 }
406
407 $this->cln_items( $order->get_id(), $cloned->get_id() );
408
409 return $cloned;
410 }*/
411
412 /**
413 * Clone items from an order to another
414 *
415 * @param int $from
416 * @param int $to
417 *
418 * @return mixed
419 * @deprecated 4.2.3.5
420 */
421 /*public function cln_items( $from, $to ) {
422 _deprecated_function( __METHOD__, '4.2.3.5' );
423 $order = learn_press_get_order( $from );
424 global $wpdb;
425
426 $query = $wpdb->prepare(
427 "
428 SELECT *
429 FROM {$wpdb->learnpress_order_items} oi
430 INNER JOIN {$wpdb->learnpress_order_itemmeta} oim ON oi.order_item_id = oim.learnpress_order_item_id
431 WHERE order_id = %d
432 ",
433 $from
434 );
435
436 $items = $order->get_items();
437 if ( $items ) {
438 $to_order = learn_press_get_order( $to );
439 if ( ! $to_order ) {
440 return false;
441 }
442
443 $to_order->remove_order_items();
444
445 foreach ( $items as $item ) {
446 $wpdb->insert(
447 $wpdb->learnpress_order_items,
448 array(
449 'order_item_name' => $item['name'],
450 'order_id' => $to,
451 )
452 );
453 $learnpress_order_item_id = $wpdb->insert_id;
454
455 $query = $wpdb->prepare(
456 "
457 SELECT *
458 FROM {$wpdb->learnpress_order_itemmeta}
459 WHERE learnpress_order_item_id = %d
460 ",
461 $item['id']
462 );
463
464 if ( $metas = $wpdb->get_results( $query ) ) {
465 foreach ( $metas as $meta ) {
466 $wpdb->insert(
467 $wpdb->learnpress_order_itemmeta,
468 array(
469 'learnpress_order_item_id' => $learnpress_order_item_id,
470 'meta_key' => $meta->meta_key,
471 'meta_value' => $meta->meta_value,
472 )
473 );
474 }
475 }
476 }
477 }
478 $this->read_items( $order );
479
480 return true;
481 }*/
482
483 /**
484 * Load order data
485 *
486 * @param LP_Order $order
487 *
488 * @return mixed
489 * @throws Exception
490 */
491 public function load( &$order ) {
492 $the_id = $order->get_id();
493 if ( ! $the_id || LP_ORDER_CPT !== learn_press_get_post_type( $the_id ) ) {
494 if ( LP_Debug::is_debug() ) {
495 throw new Exception( sprintf( __( 'Invalid order with ID "%d".', 'learnpress' ), $the_id ) );
496 }
497 }
498
499 $post = get_post( $the_id );
500 if ( $post ) {
501 $_users = get_post_meta( $order->get_id(), '_user_id' );
502 if ( $_users ) {
503 settype( $_users, 'array' );
504 } else {
505 $_users = array();
506 }
507 if ( sizeof( $_users ) > 1 ) {
508 $users = $_users;
509 } elseif ( sizeof( $_users ) == 1 ) {
510 $users = $_users[0];
511 } else {
512 $users = 0;
513 }
514
515 $lpDateTimeGmt = new LP_Datetime( $post->post_date_gmt );
516 $date_local = $lpDateTimeGmt->toSql( true );
517 $order->set_order_date( new LP_Datetime( $date_local ) );
518
519 $order->set_user_id( $users );
520 $order->set_date_modified( new LP_Datetime( $post->post_modified ) );
521 $order->set_status( str_replace( 'lp-', '', $post->post_status ) );
522 $order->set_parent_id( $post->post_parent );
523 $order->set_created_via( get_post_meta( $post->ID, '_created_via', true ) );
524 $order->set_total( get_post_meta( $post->ID, '_order_total', true ) );
525 $order->set_subtotal( get_post_meta( $post->ID, '_order_subtotal', true ) );
526 $order->set_order_key( get_post_meta( $post->ID, '_order_key', true ) );
527 $order->set_user_ip_address( get_post_meta( $post->ID, '_user_ip_address', true ) );
528 $order->set_user_agent( get_post_meta( $post->ID, '_user_agent', true ) );
529 $order->set_checkout_email( get_post_meta( $post->ID, '_checkout_email', true ) );
530 $order->set_currency( get_post_meta( $post->ID, '_order_currency', true ) );
531 $order->set_data( 'order_subtotal', get_post_meta( $post->ID, '_order_subtotal', true ) );
532 $order->set_data( 'order_total', get_post_meta( $post->ID, '_order_total', true ) );
533 $order->set_data( 'payment_method', get_post_meta( $post->ID, '_payment_method', true ) );
534 $order->set_data( 'payment_method_title', get_post_meta( $post->ID, '_payment_method_title', true ) );
535 //$order->get_items();
536 $order->read_meta();
537 }
538
539 return true;
540 }
541
542 /**
543 * Recover an order checked out by Guest for an user.
544 *
545 * @param string $order_key
546 * @param int $user_id
547 *
548 * @return bool|LP_Order|WP_Error
549 */
550 public function recover( $order_key, $user_id ) {
551 try {
552 $order = $this->get_order_by_key( $order_key );
553
554 // Validations
555 if ( ! $order ) {
556 throw new Exception( esc_html__( 'Invalid Order key.', 'learnpress' ) );
557 }
558
559 if ( ! $order->is_guest() ) {
560 throw new Exception( esc_html__( 'Order key is already assigned.', 'learnpress' ) );
561 }
562
563 $user = learn_press_get_user( $user_id );
564
565 if ( ! $user || $user instanceof LP_User_Guest ) {
566 throw new Exception( esc_html__( 'Invalid User!', 'learnpress' ) );
567 }
568
569 if ( $order->get_checkout_email() !== $user->get_email() ) {
570 throw new Exception( esc_html__( 'Invalid order key with Email!', 'learnpress' ) );
571 }
572
573 // Set user to order and update
574 $order->set_user_id( $user_id );
575 $order->save();
576
577 // Update user_id of lp_user_item
578 if ( $order->is_completed() ) {
579 $user_item_db = LP_User_Items_DB::getInstance();
580 $filter = new LP_User_Items_Filter();
581 $filter->ref_id = $order->get_id();
582 $filter->limit = -1;
583 $userItemModels = $user_item_db->get_user_items( $filter );
584 if ( ! empty( $userItemModels ) ) {
585 foreach ( $userItemModels as $userItemModelObj ) {
586 $userItemModel = new UserCourseModel( $userItemModelObj );
587 $userItemModel->user_id = $user_id;
588 $userItemModel->save();
589 }
590 }
591 }
592
593 // Trigger action
594 do_action( 'learn-press/order/recovered-successful', $order->get_id(), $user_id );
595 } catch ( Exception $ex ) {
596 return new WP_Error( 'lp_order_recover_error', $ex->getMessage() );
597 }
598
599 return $order;
600 }
601
602 /**
603 * Retrieve an order by order key.
604 *
605 * @param string $order_key
606 *
607 * @return bool|LP_Order
608 */
609 public function get_order_by_key( $order_key ) {
610 global $wpdb;
611 $query = $wpdb->prepare(
612 "
613 SELECT ID
614 FROM {$wpdb->posts} p
615 INNER JOIN {$wpdb->postmeta} pm ON pm.post_id = p.ID AND pm.meta_key = %s AND pm.meta_value = %s
616 ",
617 '_order_key',
618 $order_key
619 );
620
621 $order = false;
622 $order_id = $wpdb->get_var( $query );
623
624 if ( $order_id ) {
625 $order = learn_press_get_order( $order_id );
626 }
627
628 return $order;
629 }
630
631 public function duplicate( &$order, $args = array() ) {
632 // TODO: Implement duplicate() method.
633 }
634 }
635