PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.0
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.0, at inc/curds/class-lp-order-curd.php

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