LearnPress – WordPress LMS Plugin - Version 3.2.5.2

Version Description

~ Fixed bug can't access course after purchased. ~ Fixed bug user can't redo quiz with option 'Retake' is 1. ~ Fixed bug can't order questions by date in questions bank. ~ Extracted purchased date to date and time in order emails. ~ Show point of quiz in result page.

Download this release

Release Info

Developer tunnhn
Plugin Icon 128x128 LearnPress – WordPress LMS Plugin
Version 3.2.5.2
Comparing to
See all releases

Code changes from version 3.2.5.1 to 3.2.5.2

inc/custom-post-types/question.php CHANGED
@@ -452,12 +452,15 @@ if ( ! class_exists( 'LP_Question_Post_Type' ) ) {
452
  if ( ! $this->_is_archive() ) {
453
  return $order_by_statement;
454
  }
455
-
456
- if ( $orderby = $this->_get_orderby() && $order = $this->_get_order() ) {
457
  switch ( $orderby ) {
458
  case 'quiz-name':
459
  $order_by_statement = "q.post_title {$order}";
460
  break;
 
 
 
461
  }
462
  }
463
 
452
  if ( ! $this->_is_archive() ) {
453
  return $order_by_statement;
454
  }
455
+ $orderby = $this->_get_orderby();
456
+ if ( $orderby && $order = $this->_get_order() ) {
457
  switch ( $orderby ) {
458
  case 'quiz-name':
459
  $order_by_statement = "q.post_title {$order}";
460
  break;
461
+ case 'date':
462
+ $order_by_statement = "post_date {$order}";
463
+ break;
464
  }
465
  }
466
 
inc/lp-constants.php CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
- define( 'LEARNPRESS_VERSION', '3.2.5.1' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
+ define( 'LEARNPRESS_VERSION', '3.2.5.2' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
inc/user-item/class-lp-user-item-course.php CHANGED
@@ -122,7 +122,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
122
  $this->_items_by_item_ids[ $course_item->get_user_item_id() ] = $item_id;
123
  $this->_items_by_order[] = $item_id;
124
 
125
- $items[ $item_id ] = $course_item;
126
  }
127
  }
128
  LP_Object_Cache::set( $this->get_user_id() . '-' . $this->get_id(), $items, 'learn-press/user-course-item-objects' );
@@ -269,8 +269,8 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
269
 
270
  if ( $results === false ) {
271
  $course_result = $course->get_data( 'course_result' );
272
-
273
- if ( false === ( $results = $this->get_meta( 'course_results_' . $course_result ) ) ) {
274
  $results = $this->calculate_course_results();
275
  }
276
 
@@ -608,9 +608,9 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
608
  /**
609
  * Get completed items.
610
  *
611
- * @param string $type - Optional. Filter by type (such lp_quiz, lp_lesson) if passed
612
- * @param bool $with_total - Optional. Include total if TRUE
613
- * @param int $section_id - Optional. Get in specific section
614
  *
615
  * @return array|bool|mixed
616
  */
@@ -672,8 +672,8 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
672
  /**
673
  * Get items completed by percentage.
674
  *
675
- * @param string $type - Optional. Filter by type or not
676
- * @param int $section_id - Optional. Get in specific section
677
  *
678
  * @return float|int
679
  */
@@ -948,7 +948,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
948
  * Add new item
949
  *
950
  * @param int|array $item_id
951
- * @param int $user_id
952
  *
953
  * @return bool
954
  */
122
  $this->_items_by_item_ids[ $course_item->get_user_item_id() ] = $item_id;
123
  $this->_items_by_order[] = $item_id;
124
 
125
+ $items[ $item_id ] = $course_item;
126
  }
127
  }
128
  LP_Object_Cache::set( $this->get_user_id() . '-' . $this->get_id(), $items, 'learn-press/user-course-item-objects' );
269
 
270
  if ( $results === false ) {
271
  $course_result = $course->get_data( 'course_result' );
272
+ $results = $this->get_meta( 'course_results_' . $course_result );
273
+ if ( false === $results || ( isset( $results['result'] ) && ! $results['result'] ) ) {
274
  $results = $this->calculate_course_results();
275
  }
276
 
608
  /**
609
  * Get completed items.
610
  *
611
+ * @param string $type - Optional. Filter by type (such lp_quiz, lp_lesson) if passed
612
+ * @param bool $with_total - Optional. Include total if TRUE
613
+ * @param int $section_id - Optional. Get in specific section
614
  *
615
  * @return array|bool|mixed
616
  */
672
  /**
673
  * Get items completed by percentage.
674
  *
675
+ * @param string $type - Optional. Filter by type or not
676
+ * @param int $section_id - Optional. Get in specific section
677
  *
678
  * @return float|int
679
  */
948
  * Add new item
949
  *
950
  * @param int|array $item_id
951
+ * @param int $user_id
952
  *
953
  * @return bool
954
  */
inc/user/abstract-lp-user.php CHANGED
@@ -1522,6 +1522,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1522
  if ( $quiz = learn_press_get_quiz( $quiz_id ) ) {
1523
  $count = $quiz->get_retake_count();
1524
  if ( $count > 0 ) {
 
1525
  // Number of taken
1526
  $taken = $this->count_retaken_quiz( $quiz_id, $course_id );
1527
  if ( $taken ) {
@@ -2091,7 +2092,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2091
  */
2092
  public function get_course_access_level( $course_id ) {
2093
 
2094
- if ( false === ( $access_level = LP_Object_Cache::get( 'course-' . $course_id . '-' . $this->get_id(), 'learn-press/course-access-levels' ) ) ) {
 
2095
 
2096
  $course = learn_press_get_course( $course_id );
2097
 
@@ -2110,7 +2112,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2110
  // Default level
2111
  $access_level = apply_filters( 'learn-press/course-access-level-default', $access_level, $course_id, $this->get_id() );
2112
 
2113
- if ( ( $order = $this->get_course_order( $course_id ) ) ) {
2114
 
2115
  switch ( $order->get_status() ) {
2116
  case 'completed':
@@ -2245,8 +2247,10 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2245
  * @return bool
2246
  */
2247
  public function has_purchased_course( $course_id ) {
2248
- $purchased = apply_filters( 'learn-press/user-purchased-course', $this->get_order_status( $course_id ) == 'lp-completed', $course_id, $this->get_id() );
2249
 
 
 
 
2250
  // @deprecated
2251
  $purchased = apply_filters( 'learn_press_user_has_purchased_course', $purchased, $course_id, $this->get_id() );
2252
 
@@ -2364,10 +2368,23 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2364
  *
2365
  * @return int|LP_Order|mixed
2366
  */
2367
- public function get_course_order( $course_id, $return = 'object' ) {
2368
- $orders = $this->get_orders();
2369
- $order_id = ! empty( $orders[ $course_id ] ) ? $orders[ $course_id ] : false;
2370
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2371
  return $order_id ? ( $return === 'object' ? learn_press_get_order( $order_id ) : $order_id ) : false;
2372
  }
2373
 
1522
  if ( $quiz = learn_press_get_quiz( $quiz_id ) ) {
1523
  $count = $quiz->get_retake_count();
1524
  if ( $count > 0 ) {
1525
+ $count++;
1526
  // Number of taken
1527
  $taken = $this->count_retaken_quiz( $quiz_id, $course_id );
1528
  if ( $taken ) {
2092
  */
2093
  public function get_course_access_level( $course_id ) {
2094
 
2095
+ $access_level = LP_Object_Cache::get( 'course-' . $course_id . '-' . $this->get_id(), 'learn-press/course-access-levels' );
2096
+ if ( false === $access_level) {
2097
 
2098
  $course = learn_press_get_course( $course_id );
2099
 
2112
  // Default level
2113
  $access_level = apply_filters( 'learn-press/course-access-level-default', $access_level, $course_id, $this->get_id() );
2114
 
2115
+ if ( ( $order = $this->get_course_order( $course_id, 'object', true ) ) ) {
2116
 
2117
  switch ( $order->get_status() ) {
2118
  case 'completed':
2247
  * @return bool
2248
  */
2249
  public function has_purchased_course( $course_id ) {
 
2250
 
2251
+ $order = $this->get_course_order($course_id, 'id', true );
2252
+ $purchased = !empty($order);
2253
+ $purchased = apply_filters( 'learn-press/user-purchased-course', $purchased, $course_id, $this->get_id() );
2254
  // @deprecated
2255
  $purchased = apply_filters( 'learn_press_user_has_purchased_course', $purchased, $course_id, $this->get_id() );
2256
 
2368
  *
2369
  * @return int|LP_Order|mixed
2370
  */
 
 
 
2371
 
2372
+ public function get_course_order( $course_id, $return = 'object', $completed= false ) {
2373
+ $orders = $this->get_orders(!$completed);
2374
+ $order_id = false;
2375
+ if( isset( $orders[ $course_id ] ) ){
2376
+ if( $completed ) {
2377
+ $order_ids = $orders[ $course_id ];
2378
+ foreach ( $order_ids as $oid ) {
2379
+ if('lp-completed' == get_post_status($oid)){
2380
+ $order_id = $oid;
2381
+ break;
2382
+ }
2383
+ }
2384
+ } else {
2385
+ $order_id = ! empty( $orders[ $course_id ] ) ? $orders[ $course_id ] : false;
2386
+ }
2387
+ }
2388
  return $order_id ? ( $return === 'object' ? learn_press_get_order( $order_id ) : $order_id ) : false;
2389
  }
2390
 
inc/user/class-lp-user-factory.php CHANGED
@@ -10,19 +10,19 @@ class LP_User_Factory {
10
  * @var array
11
  */
12
  protected static $_users = array();
13
-
14
  /**
15
  * @var int
16
  */
17
  protected static $_guest_transient = 0;
18
-
19
  public static $_deleted_users = array();
20
-
21
  /**
22
  * @var LP_Background_Clear_Temp_Users
23
  */
24
  //protected static $_background_clear_users = null;
25
-
26
  /**
27
  *
28
  */
@@ -36,28 +36,28 @@ class LP_User_Factory {
36
  add_action( 'learn_press_schedule_cleanup_temp_users', array( __CLASS__, 'schedule_cleanup_temp_users' ) );
37
  add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) );
38
  ///add_action( 'init', array( __CLASS__, 'clear_temp_users' ) );
39
-
40
  /**
41
  * Filters into wp users manager
42
  */
43
  add_filter( 'users_list_table_query_args', array( __CLASS__, 'exclude_temp_users' ) );
44
-
45
  add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
46
  add_action( 'learn-press/deleted-order-item', array( __CLASS__, 'delete_user_item' ), 10, 2 );
47
  }
48
-
49
  public static function clear_temp_users() {
50
  global $wpdb;
51
  if ( $users = learn_press_get_temp_users() ) {
52
  LP()->background( 'clear-temp-users' )->push_to_queue(
53
- array(
54
- 'action' => 'clear_temp_users',
55
- 'users' => $users
56
- )
57
- );
58
  }
59
  }
60
-
61
  /**
62
  * Delete user course from user_items table after an order item is deleted.
63
  *
@@ -66,25 +66,25 @@ class LP_User_Factory {
66
  */
67
  public static function delete_user_item( $item_id, $order_id ) {
68
  $curd = new LP_User_CURD();
69
-
70
  $order = learn_press_get_order( $order_id );
71
  if ( $order ) {
72
  $course_id = learn_press_get_order_item_meta( $item_id, '_course_id' );
73
  $users = $order->get_users();
74
-
75
  if ( $users ) {
76
  foreach ( $users as $user_id ) {
77
  $curd->delete_user_item( array(
78
- 'item_id' => $course_id,
79
- 'ref_id' => $order_id,
80
- 'user_id' => $user_id
81
  ) );
82
  }
83
  }
84
  }
85
-
86
  }
87
-
88
  public static function update_user_items( $the_id, $old_status, $new_status ) {
89
  if ( ! $order = learn_press_get_order( $the_id ) ) {
90
  return;
@@ -109,7 +109,7 @@ class LP_User_Factory {
109
  }
110
  add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
111
  }
112
-
113
  /**
114
  * @param LP_Order $order
115
  * @param string $old_status
@@ -121,13 +121,14 @@ class LP_User_Factory {
121
  if ( ! $items ) {
122
  return;
123
  }
 
124
  foreach ( $order->get_users() as $user_id ) {
125
  foreach ( $items as $item ) {
126
  $item = $curd->get_user_item(
127
- $user_id,
128
- $item['course_id']
129
- );
130
- if ( $item ) {
131
  if ( is_array( $item ) ) {
132
  $item_id = $item['user_item_id'];
133
  } else {
@@ -138,7 +139,7 @@ class LP_User_Factory {
138
  }
139
  }
140
  }
141
-
142
  /**
143
  * @param LP_Order $order
144
  * @param string $old_status
@@ -149,43 +150,43 @@ class LP_User_Factory {
149
  $curd = new LP_User_CURD();
150
  $parent_order = $order->is_child() ? $order->get_parent() : $order;
151
  $items = ! $order->is_child() ? $order->get_items() : $parent_order->get_items();
152
-
153
  if ( ! $items ) {
154
  return;
155
  }
156
-
157
  if ( $order->is_multi_users() && ! $order->is_child() ) {
158
  return;
159
  }
160
-
161
  foreach ( $order->get_users() as $user_id ) {
162
-
163
  foreach ( $items as $item ) {
164
-
165
  if ( $user_item_id = self::_get_course_item( $order->get_id(), $item['course_id'], $user_id ) ) {
166
  $user_item_id = $curd->update_user_item(
167
- $user_id,
168
- $item['course_id'],
169
- array(
170
- 'ref_id' => $order->get_id(),
171
- 'ref_type' => LP_ORDER_CPT,
172
- 'parent_id' => 0
173
- )
174
- );
175
  } else {
176
  $wpdb->insert(
177
- $wpdb->learnpress_user_items,
178
- array(
179
- 'item_id' => $item['course_id'],
180
- 'ref_id' => $order->get_id(),
181
- 'ref_type' => LP_ORDER_CPT,
182
- 'user_id' => $user_id,
183
- 'item_type' => LP_COURSE_CPT
184
- )
185
- );
186
  $user_item_id = $wpdb->insert_id;
187
  }
188
-
189
  if ( $user_item_id ) {
190
  $item = $curd->get_user_item_by_id( $user_item_id );
191
  $last_status = $curd->get_user_item_meta( $user_item_id, '_last_status' );
@@ -205,14 +206,14 @@ class LP_User_Factory {
205
  $args['start_time_gmt'] = $time->toSql( false );
206
  }
207
  }
208
-
209
  $curd->update_user_item_by_id( $user_item_id, $args );
210
  }
211
  }
212
  }
213
-
214
  }
215
-
216
  protected static function _get_course_item( $order_id, $course_id, $user_id ) {
217
  global $wpdb;
218
  $query = $wpdb->prepare( "
@@ -223,10 +224,10 @@ class LP_User_Factory {
223
  AND item_id = %d
224
  AND user_id = %d
225
  ", $order_id, LP_ORDER_CPT, $course_id, $user_id );
226
-
227
  return $wpdb->get_var( $query );
228
  }
229
-
230
  /**
231
  * Hook into wp users list to exclude our temp users.
232
  *
@@ -239,27 +240,27 @@ class LP_User_Factory {
239
  if ( LP_Request::get_string( 'lp-action' ) == 'pending-request' ) {
240
  $args['include'] = self::get_pending_requests();
241
  }
242
-
243
  return $args;
244
  }
245
-
246
  public static function get_pending_requests() {
247
  if ( false === ( $pending_requests = LP_Object_Cache::get( 'pending-requests', 'lp-users' ) ) ) {
248
  global $wpdb;
249
  $query = $wpdb->prepare( "
250
  SELECT ID
251
- FROM {$wpdb->users} u
252
  INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
253
  WHERE um.meta_value = %s
254
  ", '_requested_become_teacher', 'yes' );
255
-
256
  $pending_requests = $wpdb->get_col( $query );
257
  LP_Object_Cache::set( 'pending-requests', $pending_requests, 'lp-users' );
258
  }
259
-
260
  return $pending_requests;
261
  }
262
-
263
  /**
264
  * Query all ids of temp users has created.
265
  *
@@ -269,14 +270,14 @@ class LP_User_Factory {
269
  global $wpdb;
270
  $query = $wpdb->prepare( "
271
  SELECT ID
272
- FROM {$wpdb->users} u
273
  INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = %s AND um.meta_value = %s
274
  LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = %s
275
  ", '_lp_temp_user', 'yes', '_lp_expiration' );
276
-
277
  return $wpdb->get_col( $query );
278
  }
279
-
280
  /**
281
  * Get temp user for some purpose.
282
  * This function will create a temp user in users table.
@@ -290,27 +291,27 @@ class LP_User_Factory {
290
  */
291
  public static function get_temp_user() {
292
  global $wpdb;
293
-
294
  $id = LP()->session->get( 'temp_user' );
295
-
296
  // If temp user is not set or is not exists
297
  if ( ! $id || ! get_user_by( 'id', $id ) ) {
298
-
299
  // Force to enable cookie
300
  LP()->session->set_customer_session_cookie( true );
301
-
302
  // Find temp user is not used
303
  $query = $wpdb->prepare( "
304
  SELECT ID
305
- FROM {$wpdb->users} u
306
  INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = %s AND um.meta_value = %s
307
  LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = %s
308
  WHERE um2.meta_value IS NULL
309
  LIMIT 0, 1
310
  ", '_lp_temp_user', 'yes', '_lp_expiration' );
311
-
312
  $id = $wpdb->get_var( $query );
313
-
314
  // If there is no user, create one
315
  if ( ! $id ) {
316
  $username = 'user_' . date( 'YmdHis' );
@@ -325,20 +326,20 @@ class LP_User_Factory {
325
  } else {
326
  }
327
  }
328
-
329
  if ( $id ) {
330
-
331
  // Set session and temp user expiration time
332
  update_user_meta( $id, '_lp_expiration', time() + DAY_IN_SECONDS * 2 );
333
-
334
  //
335
  delete_user_meta( $id, 'wp_capabilities' );
336
-
337
  // Set session
338
  LP()->session->set( 'temp_user', $id );
339
  }
340
  }
341
-
342
  if ( $id ) {
343
  $expiring = get_user_meta( $id, '_lp_expiration', true );
344
  // Update new expiration time if time is going to reach
@@ -346,10 +347,10 @@ class LP_User_Factory {
346
  update_user_meta( $id, '_lp_expiration', time() + DAY_IN_SECONDS * 2 );
347
  }
348
  }
349
-
350
  return new LP_User_Guest( $id );
351
  }
352
-
353
  /**
354
  * Register new schedules
355
  *
@@ -359,13 +360,13 @@ class LP_User_Factory {
359
  */
360
  public static function cron_schedules( $schedules ) {
361
  $schedules['every_three_minutes'] = array(
362
- 'interval' => self::$_guest_transient,
363
- 'display' => __( 'Every 3 Minutes', 'learnpress' )
364
  );
365
-
366
  return $schedules;
367
  }
368
-
369
  /**
370
  * Register schedule event to cleanup data of temp users who have took quiz
371
  */
@@ -374,14 +375,14 @@ class LP_User_Factory {
374
  wp_schedule_event( time(), 'every_three_minutes', 'learn_press_schedule_cleanup_temp_users' );
375
  }
376
  }
377
-
378
  /**
379
  * Clear schedule event while deactivating LP
380
  */
381
  public static function deregister_event() {
382
  wp_clear_scheduled_hook( 'learn_press_schedule_cleanup_temp_users' );
383
  }
384
-
385
  /**
386
  * Call this function hourly
387
  */
@@ -393,7 +394,7 @@ class LP_User_Factory {
393
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta d ON c.user_item_id = d.learnpress_user_item_id AND d.meta_key = %s
394
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta e ON c.user_item_id = e.learnpress_user_item_id AND e.meta_key = %s AND e.meta_value < TIMESTAMPADD(SECOND, %d, NOW())
395
  ", 'temp_user_id', 'temp_user_time', self::$_guest_transient );
396
-
397
  if ( $uids = $wpdb->get_col( $query ) ) {
398
  $query = $wpdb->prepare( "
399
  DELETE a.*, b.*
@@ -406,7 +407,7 @@ class LP_User_Factory {
406
  $wpdb->query( $query );
407
  }
408
  }
409
-
410
  /**
411
  * Generate unique id for anonymous user
412
  */
@@ -419,14 +420,14 @@ class LP_User_Factory {
419
  set_transient( 'learn_press_user_guest_' . $id, $id, self::$_guest_transient );
420
  }
421
  }
422
-
423
  return $id;
424
  }
425
-
426
  public static function get_guest_id() {
427
  return LP()->session->guest_user_id;// empty( $_COOKIE['learn_press_user_guest_id'] ) ? false : $_COOKIE['learn_press_user_guest_id'];
428
  }
429
-
430
  /**
431
  * @param $the_user
432
  * @param bool $force
@@ -444,7 +445,7 @@ class LP_User_Factory {
444
  } elseif ( null === $the_user ) {
445
  $the_id = get_current_user_id();
446
  }
447
-
448
  $user_class = self::get_user_class( $the_id );
449
  if ( $user_class instanceof LP_User_Guest ) {
450
  $the_id = self::get_guest_id();
@@ -452,10 +453,10 @@ class LP_User_Factory {
452
  if ( empty( self::$_users[ $the_id ] ) || $force ) {
453
  self::$_users[ $the_id ] = new $user_class( $the_id );
454
  }
455
-
456
  return self::$_users[ $the_id ];
457
  }
458
-
459
  /**
460
  * Get class name for User Object
461
  *
@@ -483,10 +484,10 @@ class LP_User_Factory {
483
  $is_logged_in = function_exists( 'is_user_logged_in' ) && is_user_logged_in();
484
  $class = $is_logged_in ? 'LP_User' : 'LP_User_Guest';
485
  }
486
-
487
  return apply_filters( 'learn_press_user_class', $class );
488
  }
489
-
490
  /**
491
  * Clear temp data for guest user
492
  *
@@ -496,15 +497,15 @@ class LP_User_Factory {
496
  if ( $temp_id = self::get_guest_id() ) {
497
  learn_press_remove_cookie( 'learn_press_user_guest_id' );
498
  delete_transient( 'learn_press_user_guest_' . $temp_id );
499
-
500
  global $wpdb;
501
-
502
  $query = $wpdb->prepare( "
503
  SELECT user_item_id
504
  FROM {$wpdb->prefix}learnpress_user_items a
505
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta b ON a.user_item_id = b.learnpress_user_item_id AND b.meta_key = %s And b.meta_value = %s
506
  ", 'temp_user_id', 'yes' );
507
-
508
  $user_item_ids = $wpdb->get_row( $query );
509
  if ( $user_item_ids ) {
510
  $query = $wpdb->prepare( "
@@ -518,21 +519,21 @@ class LP_User_Factory {
518
  }
519
  }
520
  }
521
-
522
  /**
523
  * @param int $quiz_id
524
  * @param int $course_id
525
  * @param int $user_id
526
  */
527
  public static function start_quiz( $quiz_id, $course_id, $user_id ) {
528
-
529
  if ( $user = learn_press_get_user( $user_id ) ) {
530
  if ( $item = $user->get_item_data( $quiz_id, $course_id ) ) {
531
  self::_update_user_item_meta( $item, $quiz_id, $course_id, $user_id );
532
  }
533
  }
534
  }
535
-
536
  /**
537
  * @param $item
538
  * @param $quiz_id
@@ -542,7 +543,7 @@ class LP_User_Factory {
542
  public static function retake_quiz( $item, $quiz_id, $course_id, $user_id ) {
543
  self::_update_user_item_meta( $item, $quiz_id, $course_id, $user_id );
544
  }
545
-
546
  /**
547
  * @param LP_User_Item $item
548
  * @param int $quiz_id
@@ -553,11 +554,11 @@ class LP_User_Factory {
553
  if ( get_user_by( 'id', $user_id ) ) {
554
  return;
555
  }
556
-
557
  if ( ! $item ) {
558
  return;
559
  }
560
-
561
  learn_press_add_user_item_meta( $item->get_user_item_id(), 'temp_user_id', 'yes' );
562
  learn_press_add_user_item_meta( $item->get_user_item_id(), 'temp_user_time', date( 'Y-m-d H:i:s', time() ) );
563
  }
10
  * @var array
11
  */
12
  protected static $_users = array();
13
+
14
  /**
15
  * @var int
16
  */
17
  protected static $_guest_transient = 0;
18
+
19
  public static $_deleted_users = array();
20
+
21
  /**
22
  * @var LP_Background_Clear_Temp_Users
23
  */
24
  //protected static $_background_clear_users = null;
25
+
26
  /**
27
  *
28
  */
36
  add_action( 'learn_press_schedule_cleanup_temp_users', array( __CLASS__, 'schedule_cleanup_temp_users' ) );
37
  add_filter( 'cron_schedules', array( __CLASS__, 'cron_schedules' ) );
38
  ///add_action( 'init', array( __CLASS__, 'clear_temp_users' ) );
39
+
40
  /**
41
  * Filters into wp users manager
42
  */
43
  add_filter( 'users_list_table_query_args', array( __CLASS__, 'exclude_temp_users' ) );
44
+
45
  add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
46
  add_action( 'learn-press/deleted-order-item', array( __CLASS__, 'delete_user_item' ), 10, 2 );
47
  }
48
+
49
  public static function clear_temp_users() {
50
  global $wpdb;
51
  if ( $users = learn_press_get_temp_users() ) {
52
  LP()->background( 'clear-temp-users' )->push_to_queue(
53
+ array(
54
+ 'action' => 'clear_temp_users',
55
+ 'users' => $users
56
+ )
57
+ );
58
  }
59
  }
60
+
61
  /**
62
  * Delete user course from user_items table after an order item is deleted.
63
  *
66
  */
67
  public static function delete_user_item( $item_id, $order_id ) {
68
  $curd = new LP_User_CURD();
69
+
70
  $order = learn_press_get_order( $order_id );
71
  if ( $order ) {
72
  $course_id = learn_press_get_order_item_meta( $item_id, '_course_id' );
73
  $users = $order->get_users();
74
+
75
  if ( $users ) {
76
  foreach ( $users as $user_id ) {
77
  $curd->delete_user_item( array(
78
+ 'item_id' => $course_id,
79
+ 'ref_id' => $order_id,
80
+ 'user_id' => $user_id
81
  ) );
82
  }
83
  }
84
  }
85
+
86
  }
87
+
88
  public static function update_user_items( $the_id, $old_status, $new_status ) {
89
  if ( ! $order = learn_press_get_order( $the_id ) ) {
90
  return;
109
  }
110
  add_action( 'learn-press/order/status-changed', array( __CLASS__, 'update_user_items' ), 10, 3 );
111
  }
112
+
113
  /**
114
  * @param LP_Order $order
115
  * @param string $old_status
121
  if ( ! $items ) {
122
  return;
123
  }
124
+ $order_id = $order->get_id();
125
  foreach ( $order->get_users() as $user_id ) {
126
  foreach ( $items as $item ) {
127
  $item = $curd->get_user_item(
128
+ $user_id,
129
+ $item['course_id']
130
+ );
131
+ if ( $item && intval($item['ref_id'])== intval($order_id) ) {
132
  if ( is_array( $item ) ) {
133
  $item_id = $item['user_item_id'];
134
  } else {
139
  }
140
  }
141
  }
142
+
143
  /**
144
  * @param LP_Order $order
145
  * @param string $old_status
150
  $curd = new LP_User_CURD();
151
  $parent_order = $order->is_child() ? $order->get_parent() : $order;
152
  $items = ! $order->is_child() ? $order->get_items() : $parent_order->get_items();
153
+
154
  if ( ! $items ) {
155
  return;
156
  }
157
+
158
  if ( $order->is_multi_users() && ! $order->is_child() ) {
159
  return;
160
  }
161
+
162
  foreach ( $order->get_users() as $user_id ) {
163
+
164
  foreach ( $items as $item ) {
165
+
166
  if ( $user_item_id = self::_get_course_item( $order->get_id(), $item['course_id'], $user_id ) ) {
167
  $user_item_id = $curd->update_user_item(
168
+ $user_id,
169
+ $item['course_id'],
170
+ array(
171
+ 'ref_id' => $order->get_id(),
172
+ 'ref_type' => LP_ORDER_CPT,
173
+ 'parent_id' => 0
174
+ )
175
+ );
176
  } else {
177
  $wpdb->insert(
178
+ $wpdb->learnpress_user_items,
179
+ array(
180
+ 'item_id' => $item['course_id'],
181
+ 'ref_id' => $order->get_id(),
182
+ 'ref_type' => LP_ORDER_CPT,
183
+ 'user_id' => $user_id,
184
+ 'item_type' => LP_COURSE_CPT
185
+ )
186
+ );
187
  $user_item_id = $wpdb->insert_id;
188
  }
189
+
190
  if ( $user_item_id ) {
191
  $item = $curd->get_user_item_by_id( $user_item_id );
192
  $last_status = $curd->get_user_item_meta( $user_item_id, '_last_status' );
206
  $args['start_time_gmt'] = $time->toSql( false );
207
  }
208
  }
209
+
210
  $curd->update_user_item_by_id( $user_item_id, $args );
211
  }
212
  }
213
  }
214
+
215
  }
216
+
217
  protected static function _get_course_item( $order_id, $course_id, $user_id ) {
218
  global $wpdb;
219
  $query = $wpdb->prepare( "
224
  AND item_id = %d
225
  AND user_id = %d
226
  ", $order_id, LP_ORDER_CPT, $course_id, $user_id );
227
+
228
  return $wpdb->get_var( $query );
229
  }
230
+
231
  /**
232
  * Hook into wp users list to exclude our temp users.
233
  *
240
  if ( LP_Request::get_string( 'lp-action' ) == 'pending-request' ) {
241
  $args['include'] = self::get_pending_requests();
242
  }
243
+
244
  return $args;
245
  }
246
+
247
  public static function get_pending_requests() {
248
  if ( false === ( $pending_requests = LP_Object_Cache::get( 'pending-requests', 'lp-users' ) ) ) {
249
  global $wpdb;
250
  $query = $wpdb->prepare( "
251
  SELECT ID
252
+ FROM {$wpdb->users} u
253
  INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s
254
  WHERE um.meta_value = %s
255
  ", '_requested_become_teacher', 'yes' );
256
+
257
  $pending_requests = $wpdb->get_col( $query );
258
  LP_Object_Cache::set( 'pending-requests', $pending_requests, 'lp-users' );
259
  }
260
+
261
  return $pending_requests;
262
  }
263
+
264
  /**
265
  * Query all ids of temp users has created.
266
  *
270
  global $wpdb;
271
  $query = $wpdb->prepare( "
272
  SELECT ID
273
+ FROM {$wpdb->users} u
274
  INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = %s AND um.meta_value = %s
275
  LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = %s
276
  ", '_lp_temp_user', 'yes', '_lp_expiration' );
277
+
278
  return $wpdb->get_col( $query );
279
  }
280
+
281
  /**
282
  * Get temp user for some purpose.
283
  * This function will create a temp user in users table.
291
  */
292
  public static function get_temp_user() {
293
  global $wpdb;
294
+
295
  $id = LP()->session->get( 'temp_user' );
296
+
297
  // If temp user is not set or is not exists
298
  if ( ! $id || ! get_user_by( 'id', $id ) ) {
299
+
300
  // Force to enable cookie
301
  LP()->session->set_customer_session_cookie( true );
302
+
303
  // Find temp user is not used
304
  $query = $wpdb->prepare( "
305
  SELECT ID
306
+ FROM {$wpdb->users} u
307
  INNER JOIN {$wpdb->usermeta} um ON u.ID = um.user_id AND um.meta_key = %s AND um.meta_value = %s
308
  LEFT JOIN {$wpdb->usermeta} um2 ON u.ID = um2.user_id AND um2.meta_key = %s
309
  WHERE um2.meta_value IS NULL
310
  LIMIT 0, 1
311
  ", '_lp_temp_user', 'yes', '_lp_expiration' );
312
+
313
  $id = $wpdb->get_var( $query );
314
+
315
  // If there is no user, create one
316
  if ( ! $id ) {
317
  $username = 'user_' . date( 'YmdHis' );
326
  } else {
327
  }
328
  }
329
+
330
  if ( $id ) {
331
+
332
  // Set session and temp user expiration time
333
  update_user_meta( $id, '_lp_expiration', time() + DAY_IN_SECONDS * 2 );
334
+
335
  //
336
  delete_user_meta( $id, 'wp_capabilities' );
337
+
338
  // Set session
339
  LP()->session->set( 'temp_user', $id );
340
  }
341
  }
342
+
343
  if ( $id ) {
344
  $expiring = get_user_meta( $id, '_lp_expiration', true );
345
  // Update new expiration time if time is going to reach
347
  update_user_meta( $id, '_lp_expiration', time() + DAY_IN_SECONDS * 2 );
348
  }
349
  }
350
+
351
  return new LP_User_Guest( $id );
352
  }
353
+
354
  /**
355
  * Register new schedules
356
  *
360
  */
361
  public static function cron_schedules( $schedules ) {
362
  $schedules['every_three_minutes'] = array(
363
+ 'interval' => self::$_guest_transient,
364
+ 'display' => __( 'Every 3 Minutes', 'learnpress' )
365
  );
366
+
367
  return $schedules;
368
  }
369
+
370
  /**
371
  * Register schedule event to cleanup data of temp users who have took quiz
372
  */
375
  wp_schedule_event( time(), 'every_three_minutes', 'learn_press_schedule_cleanup_temp_users' );
376
  }
377
  }
378
+
379
  /**
380
  * Clear schedule event while deactivating LP
381
  */
382
  public static function deregister_event() {
383
  wp_clear_scheduled_hook( 'learn_press_schedule_cleanup_temp_users' );
384
  }
385
+
386
  /**
387
  * Call this function hourly
388
  */
394
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta d ON c.user_item_id = d.learnpress_user_item_id AND d.meta_key = %s
395
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta e ON c.user_item_id = e.learnpress_user_item_id AND e.meta_key = %s AND e.meta_value < TIMESTAMPADD(SECOND, %d, NOW())
396
  ", 'temp_user_id', 'temp_user_time', self::$_guest_transient );
397
+
398
  if ( $uids = $wpdb->get_col( $query ) ) {
399
  $query = $wpdb->prepare( "
400
  DELETE a.*, b.*
407
  $wpdb->query( $query );
408
  }
409
  }
410
+
411
  /**
412
  * Generate unique id for anonymous user
413
  */
420
  set_transient( 'learn_press_user_guest_' . $id, $id, self::$_guest_transient );
421
  }
422
  }
423
+
424
  return $id;
425
  }
426
+
427
  public static function get_guest_id() {
428
  return LP()->session->guest_user_id;// empty( $_COOKIE['learn_press_user_guest_id'] ) ? false : $_COOKIE['learn_press_user_guest_id'];
429
  }
430
+
431
  /**
432
  * @param $the_user
433
  * @param bool $force
445
  } elseif ( null === $the_user ) {
446
  $the_id = get_current_user_id();
447
  }
448
+
449
  $user_class = self::get_user_class( $the_id );
450
  if ( $user_class instanceof LP_User_Guest ) {
451
  $the_id = self::get_guest_id();
453
  if ( empty( self::$_users[ $the_id ] ) || $force ) {
454
  self::$_users[ $the_id ] = new $user_class( $the_id );
455
  }
456
+
457
  return self::$_users[ $the_id ];
458
  }
459
+
460
  /**
461
  * Get class name for User Object
462
  *
484
  $is_logged_in = function_exists( 'is_user_logged_in' ) && is_user_logged_in();
485
  $class = $is_logged_in ? 'LP_User' : 'LP_User_Guest';
486
  }
487
+
488
  return apply_filters( 'learn_press_user_class', $class );
489
  }
490
+
491
  /**
492
  * Clear temp data for guest user
493
  *
497
  if ( $temp_id = self::get_guest_id() ) {
498
  learn_press_remove_cookie( 'learn_press_user_guest_id' );
499
  delete_transient( 'learn_press_user_guest_' . $temp_id );
500
+
501
  global $wpdb;
502
+
503
  $query = $wpdb->prepare( "
504
  SELECT user_item_id
505
  FROM {$wpdb->prefix}learnpress_user_items a
506
  INNER JOIN {$wpdb->prefix}learnpress_user_itemmeta b ON a.user_item_id = b.learnpress_user_item_id AND b.meta_key = %s And b.meta_value = %s
507
  ", 'temp_user_id', 'yes' );
508
+
509
  $user_item_ids = $wpdb->get_row( $query );
510
  if ( $user_item_ids ) {
511
  $query = $wpdb->prepare( "
519
  }
520
  }
521
  }
522
+
523
  /**
524
  * @param int $quiz_id
525
  * @param int $course_id
526
  * @param int $user_id
527
  */
528
  public static function start_quiz( $quiz_id, $course_id, $user_id ) {
529
+
530
  if ( $user = learn_press_get_user( $user_id ) ) {
531
  if ( $item = $user->get_item_data( $quiz_id, $course_id ) ) {
532
  self::_update_user_item_meta( $item, $quiz_id, $course_id, $user_id );
533
  }
534
  }
535
  }
536
+
537
  /**
538
  * @param $item
539
  * @param $quiz_id
543
  public static function retake_quiz( $item, $quiz_id, $course_id, $user_id ) {
544
  self::_update_user_item_meta( $item, $quiz_id, $course_id, $user_id );
545
  }
546
+
547
  /**
548
  * @param LP_User_Item $item
549
  * @param int $quiz_id
554
  if ( get_user_by( 'id', $user_id ) ) {
555
  return;
556
  }
557
+
558
  if ( ! $item ) {
559
  return;
560
  }
561
+
562
  learn_press_add_user_item_meta( $item->get_user_item_id(), 'temp_user_id', 'yes' );
563
  learn_press_add_user_item_meta( $item->get_user_item_id(), 'temp_user_time', date( 'Y-m-d H:i:s', time() ) );
564
  }
learnpress.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: LearnPress
4
  Plugin URI: http://thimpress.com/learnpress
5
  Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
6
  Author: ThimPress
7
- Version: 3.2.5.1
8
  Author URI: http://thimpress.com
9
  Requires at least: 3.8
10
  Tested up to: 5.0.2
4
  Plugin URI: http://thimpress.com/learnpress
5
  Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
6
  Author: ThimPress
7
+ Version: 3.2.5.2
8
  Author URI: http://thimpress.com
9
  Requires at least: 3.8
10
  Tested up to: 5.0.2
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: WordPress LMS, LMS, eLearning, e-Learning, Learning Management System, LMS WordPress, Course, Courses, Quiz, Quizzes, Training, Guru, Sell Courses
5
  Requires at least: 3.8
6
  Tested up to: 5.0.2
7
- Stable tag: 3.2.5.1
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -199,6 +199,13 @@ https://www.transifex.com/projects/p/learnpress/
199
  8. Add-ons of LearnPress.
200
 
201
  == Changelog ==
 
 
 
 
 
 
 
202
  = 3.2.5.1 =
203
  ~ Fixed can not next/prev question when doing quiz.
204
  ~ Fixed get wrong total student of a course.
4
  Tags: WordPress LMS, LMS, eLearning, e-Learning, Learning Management System, LMS WordPress, Course, Courses, Quiz, Quizzes, Training, Guru, Sell Courses
5
  Requires at least: 3.8
6
  Tested up to: 5.0.2
7
+ Stable tag: 3.2.5.2
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
199
  8. Add-ons of LearnPress.
200
 
201
  == Changelog ==
202
+ = 3.2.5.2 =
203
+ ~ Fixed bug can't access course after purchased.
204
+ ~ Fixed bug user can't redo quiz with option 'Retake' is 1.
205
+ ~ Fixed bug can't order questions by date in questions bank.
206
+ ~ Extracted purchased date to date and time in order emails.
207
+ ~ Show point of quiz in result page.
208
+
209
  = 3.2.5.1 =
210
  ~ Fixed can not next/prev question when doing quiz.
211
  ~ Fixed get wrong total student of a course.
templates/content-quiz/result.php CHANGED
@@ -38,6 +38,10 @@ if ( $quiz_data->is_review_questions() ) {
38
  <label><?php echo _x( 'Time spend', 'quiz-result', 'learnpress' ); ?></label>
39
  <p><?php echo $result['time_spend']; ?></p>
40
  </li>
 
 
 
 
41
  <li class="result-statistic-field">
42
  <label><?php echo _x( 'Questions', 'quiz-result', 'learnpress' ); ?></label>
43
  <p><?php echo $quiz->count_questions(); ?></p>
38
  <label><?php echo _x( 'Time spend', 'quiz-result', 'learnpress' ); ?></label>
39
  <p><?php echo $result['time_spend']; ?></p>
40
  </li>
41
+ <li class="result-statistic-field">
42
+ <label><?php echo _x( 'Point', 'quiz-result', 'learnpress' ); ?></label>
43
+ <p><?php echo $result['user_mark'] . ' / ' . $result['mark']; ?></p>
44
+ </li>
45
  <li class="result-statistic-field">
46
  <label><?php echo _x( 'Questions', 'quiz-result', 'learnpress' ); ?></label>
47
  <p><?php echo $quiz->count_questions(); ?></p>
templates/emails/order-items-table.php CHANGED
@@ -43,7 +43,7 @@ if ( ! $items ) {
43
  </tr>
44
  <tr>
45
  <th><?php _e( 'Purchase Date', 'learnpress' ); ?></th>
46
- <td><?php echo $order->get_order_date(); ?></td>
47
  </tr>
48
  <tr>
49
  <th><?php _e( 'Payment Method', 'learnpress' ); ?></th>
43
  </tr>
44
  <tr>
45
  <th><?php _e( 'Purchase Date', 'learnpress' ); ?></th>
46
+ <td><?php echo date_i18n( get_option( 'date_format' ), strtotime( $order->get_order_date( 'timestamp' ) ) ); ?></td>
47
  </tr>
48
  <tr>
49
  <th><?php _e( 'Payment Method', 'learnpress' ); ?></th>