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 | 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 +5 -2
- inc/lp-constants.php +1 -1
- inc/user-item/class-lp-user-item-course.php +9 -9
- inc/user/abstract-lp-user.php +23 -6
- inc/user/class-lp-user-factory.php +103 -102
- learnpress.php +1 -1
- readme.txt +8 -1
- templates/content-quiz/result.php +4 -0
- templates/emails/order-items-table.php +1 -1
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
|
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.
|
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 ]
|
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 ===
|
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
|
612 |
-
* @param bool
|
613 |
-
* @param int
|
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
|
676 |
-
* @param int
|
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
|
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 |
-
|
|
|
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 |
-
|
54 |
-
|
55 |
-
|
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 |
-
|
79 |
-
|
80 |
-
|
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 |
-
|
128 |
-
|
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 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
-
|
173 |
-
|
174 |
-
|
175 |
} else {
|
176 |
$wpdb->insert(
|
177 |
-
|
178 |
-
|
179 |
-
|
180 |
-
|
181 |
-
|
182 |
-
|
183 |
-
|
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 |
-
|
363 |
-
|
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.
|
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.
|
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>
|