Version Description
~ Fixed css conflict with text block of vc. ~ Fixed show message 'Out of stock' for course reached limitation users. ~ Fixed show checked answers when review quiz. ~ Fixed review quiz option does not work properly. ~ Fixed update view after removing order's items.
Download this release
Release Info
Developer | tunnhn |
Plugin | LearnPress – WordPress LMS Plugin |
Version | 3.2.6.3 |
Comparing to | |
See all releases |
Code changes from version 3.2.6.2 to 3.2.6.3
- assets/css/admin/admin.css +1 -1
- inc/admin/class-lp-admin-ajax.php +10 -0
- inc/admin/editor/class-lp-admin-editor-quiz.php +1 -1
- inc/class-lp-request-handler.php +1 -1
- inc/custom-post-types/quiz.php +7 -4
- inc/lp-constants.php +1 -1
- inc/lp-core-functions.php +1 -1
- inc/lp-template-functions.php +4 -0
- inc/order/class-lp-order.php +1 -1
- inc/question/class-lp-question-answers.php +17 -7
- inc/user-item/class-lp-user-item-course.php +5 -1
- learnpress.php +1 -1
- readme.txt +9 -2
- templates/widgets/featured-courses/default.php +3 -3
- templates/widgets/popular-courses/default.php +2 -4
- templates/widgets/recent-courses/default.php +3 -3
assets/css/admin/admin.css
CHANGED
@@ -390,7 +390,7 @@
|
|
390 |
.rwmb-duration {
|
391 |
border: 1px solid #ddd; }
|
392 |
|
393 |
-
.clearfix {
|
394 |
clear: both;
|
395 |
height: 0;
|
396 |
opacity: 0; }
|
390 |
.rwmb-duration {
|
391 |
border: 1px solid #ddd; }
|
392 |
|
393 |
+
ul .clearfix {
|
394 |
clear: both;
|
395 |
height: 0;
|
396 |
opacity: 0; }
|
inc/admin/class-lp-admin-ajax.php
CHANGED
@@ -606,10 +606,20 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
|
|
606 |
$currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
|
607 |
$order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
|
608 |
$order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
609 |
|
610 |
learn_press_send_json(
|
611 |
array(
|
612 |
'result' => 'success',
|
|
|
613 |
'order_data' => $order_data
|
614 |
)
|
615 |
);
|
606 |
$currency_symbol = learn_press_get_currency_symbol( $order_data['currency'] );
|
607 |
$order_data['subtotal_html'] = learn_press_format_price( $order_data['subtotal'], $currency_symbol );
|
608 |
$order_data['total_html'] = learn_press_format_price( $order_data['total'], $currency_symbol );
|
609 |
+
$order_items = $order->get_items();
|
610 |
+
if ( $order_items ) {
|
611 |
+
$html = '';
|
612 |
+
foreach ( $order_items as $item ) {
|
613 |
+
ob_start();
|
614 |
+
include learn_press_get_admin_view( 'meta-boxes/order/order-item.php' );
|
615 |
+
$html .= ob_get_clean();
|
616 |
+
}
|
617 |
+
}
|
618 |
|
619 |
learn_press_send_json(
|
620 |
array(
|
621 |
'result' => 'success',
|
622 |
+
'item_html' => $html,
|
623 |
'order_data' => $order_data
|
624 |
)
|
625 |
);
|
inc/admin/editor/class-lp-admin-editor-quiz.php
CHANGED
@@ -68,7 +68,7 @@ class LP_Admin_Editor_Quiz extends LP_Admin_Editor {
|
|
68 |
*/
|
69 |
public function get_question_data_to_quiz_editor( $question, $object = false, $args = array() ) {
|
70 |
|
71 |
-
if ( ! $object ) {
|
72 |
if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
|
73 |
return array();
|
74 |
}
|
68 |
*/
|
69 |
public function get_question_data_to_quiz_editor( $question, $object = false, $args = array() ) {
|
70 |
|
71 |
+
if ( ! $object || ! $question ) {
|
72 |
if ( get_post_type( $question ) !== LP_QUESTION_CPT ) {
|
73 |
return array();
|
74 |
}
|
inc/class-lp-request-handler.php
CHANGED
@@ -823,7 +823,7 @@ class LP_Request {
|
|
823 |
|
824 |
LP_Request::init();
|
825 |
|
826 |
-
// Backward compatibility for 3.2.6.
|
827 |
class LP_Request_Handler extends LP_Request {
|
828 |
|
829 |
}
|
823 |
|
824 |
LP_Request::init();
|
825 |
|
826 |
+
// Backward compatibility for 3.2.6.3
|
827 |
class LP_Request_Handler extends LP_Request {
|
828 |
|
829 |
}
|
inc/custom-post-types/quiz.php
CHANGED
@@ -203,10 +203,13 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
|
|
203 |
* @param $post_id
|
204 |
*/
|
205 |
public function before_delete_quiz( $post_id ) {
|
|
|
|
|
|
|
206 |
// quiz curd
|
207 |
$curd = new LP_Quiz_CURD();
|
208 |
// remove question from course items
|
209 |
-
$curd->delete( $
|
210 |
}
|
211 |
|
212 |
/**
|
@@ -371,7 +374,7 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
|
|
371 |
|
372 |
// append new column after title column
|
373 |
$pos = array_search( 'title', array_keys( $columns ) );
|
374 |
-
if ( false !== $pos && !array_key_exists( LP_COURSE_CPT, $columns ) ) {
|
375 |
$columns = array_merge(
|
376 |
array_slice( $columns, 0, $pos + 1 ),
|
377 |
array(
|
@@ -397,7 +400,7 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
|
|
397 |
* Display content for custom column
|
398 |
*
|
399 |
* @param string $name
|
400 |
-
* @param int
|
401 |
*/
|
402 |
public function columns_content( $name, $post_id = 0 ) {
|
403 |
global $post;
|
@@ -538,7 +541,7 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
|
|
538 |
*/
|
539 |
public function sortable_columns( $columns ) {
|
540 |
$columns['author'] = 'author';
|
541 |
-
$columns[LP_COURSE_CPT]
|
542 |
$columns['num_of_question'] = 'question-count';
|
543 |
|
544 |
return $columns;
|
203 |
* @param $post_id
|
204 |
*/
|
205 |
public function before_delete_quiz( $post_id ) {
|
206 |
+
if ( get_post_type( $post_id ) !== LP_QUIZ_CPT ) {
|
207 |
+
return;
|
208 |
+
}
|
209 |
// quiz curd
|
210 |
$curd = new LP_Quiz_CURD();
|
211 |
// remove question from course items
|
212 |
+
$curd->delete( $post_id );
|
213 |
}
|
214 |
|
215 |
/**
|
374 |
|
375 |
// append new column after title column
|
376 |
$pos = array_search( 'title', array_keys( $columns ) );
|
377 |
+
if ( false !== $pos && ! array_key_exists( LP_COURSE_CPT, $columns ) ) {
|
378 |
$columns = array_merge(
|
379 |
array_slice( $columns, 0, $pos + 1 ),
|
380 |
array(
|
400 |
* Display content for custom column
|
401 |
*
|
402 |
* @param string $name
|
403 |
+
* @param int $post_id
|
404 |
*/
|
405 |
public function columns_content( $name, $post_id = 0 ) {
|
406 |
global $post;
|
541 |
*/
|
542 |
public function sortable_columns( $columns ) {
|
543 |
$columns['author'] = 'author';
|
544 |
+
$columns[ LP_COURSE_CPT ] = 'course-name';
|
545 |
$columns['num_of_question'] = 'question-count';
|
546 |
|
547 |
return $columns;
|
inc/lp-constants.php
CHANGED
@@ -4,7 +4,7 @@
|
|
4 |
*/
|
5 |
$upload_dir = wp_upload_dir();
|
6 |
// version
|
7 |
-
define( 'LEARNPRESS_VERSION', '3.2.6.
|
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.6.3' );
|
8 |
|
9 |
define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
|
10 |
|
inc/lp-core-functions.php
CHANGED
@@ -564,7 +564,7 @@ function learn_press_setup_pages() {
|
|
564 |
}
|
565 |
|
566 |
$query = $wpdb->prepare( "
|
567 |
-
SELECT ID, post_title, post_name, post_content, post_parent, post_type
|
568 |
FROM {$wpdb->posts}
|
569 |
WHERE %d AND ID IN(" . join( ',', $page_ids ) . ")
|
570 |
AND post_status <> %s
|
564 |
}
|
565 |
|
566 |
$query = $wpdb->prepare( "
|
567 |
+
SELECT ID, post_title, post_name, post_date, post_date_gmt, post_modified, post_modified_gmt, post_content, post_parent, post_type
|
568 |
FROM {$wpdb->posts}
|
569 |
WHERE %d AND ID IN(" . join( ',', $page_ids ) . ")
|
570 |
AND post_status <> %s
|
inc/lp-template-functions.php
CHANGED
@@ -37,6 +37,10 @@ if ( ! function_exists( 'learn_press_course_purchase_button' ) ) {
|
|
37 |
|
38 |
// If course is reached limitation.
|
39 |
if ( ! $course->is_in_stock() ) {
|
|
|
|
|
|
|
|
|
40 |
return;
|
41 |
}
|
42 |
|
37 |
|
38 |
// If course is reached limitation.
|
39 |
if ( ! $course->is_in_stock() ) {
|
40 |
+
if ( $message = apply_filters( 'learn-press/maximum-students-reach', __( 'This course is out of stock', 'learnpress' ) ) ) {
|
41 |
+
learn_press_display_message( $message );
|
42 |
+
}
|
43 |
+
|
44 |
return;
|
45 |
}
|
46 |
|
inc/order/class-lp-order.php
CHANGED
@@ -739,7 +739,7 @@ if ( ! class_exists( 'LP_Order' ) ) {
|
|
739 |
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_order_items WHERE order_item_id = %d", $item_id ) );
|
740 |
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_order_itemmeta WHERE learnpress_order_item_id = %d", $item_id ) );
|
741 |
|
742 |
-
|
743 |
|
744 |
/**
|
745 |
* @since 3.0.0
|
739 |
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_order_items WHERE order_item_id = %d", $item_id ) );
|
740 |
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}learnpress_order_itemmeta WHERE learnpress_order_item_id = %d", $item_id ) );
|
741 |
|
742 |
+
LP_Object_Cache::delete( 'order-' . $this->get_id(), 'learn-press/order-items' );
|
743 |
|
744 |
/**
|
745 |
* @since 3.0.0
|
inc/question/class-lp-question-answers.php
CHANGED
@@ -53,7 +53,7 @@ if ( ! class_exists( 'LP_Question_Answers' ) ) {
|
|
53 |
* LP_Question_Answers constructor.
|
54 |
*
|
55 |
* @param LP_Question $question
|
56 |
-
* @param mixed
|
57 |
*
|
58 |
* @param $raw
|
59 |
*/
|
@@ -109,7 +109,7 @@ if ( ! class_exists( 'LP_Question_Answers' ) ) {
|
|
109 |
* Set new option for an answer
|
110 |
*
|
111 |
* @param int|array $id
|
112 |
-
* @param mixed
|
113 |
*/
|
114 |
public function set_answer_option( $id, $options = '' ) {
|
115 |
if ( is_array( $id ) && func_num_args() == 1 ) {
|
@@ -185,7 +185,7 @@ if ( ! class_exists( 'LP_Question_Answers' ) ) {
|
|
185 |
* Set answer option by offset.
|
186 |
*
|
187 |
* @param int|string $offset
|
188 |
-
* @param mixed
|
189 |
*/
|
190 |
public function offsetSet( $offset, $value ) {
|
191 |
$this->_answers[ $offset ] = $value;
|
@@ -324,7 +324,7 @@ if ( ! class_exists( 'LP_Question_Answer_Option' ) ) {
|
|
324 |
* LP_Question_Answer_Option constructor.
|
325 |
*
|
326 |
* @param LP_Question $question
|
327 |
-
* @param mixed
|
328 |
*/
|
329 |
public function __construct( $question, $data ) {
|
330 |
$this->_data = $data;
|
@@ -386,12 +386,11 @@ if ( ! class_exists( 'LP_Question_Answer_Option' ) ) {
|
|
386 |
if ( $more && is_array( $more ) ) {
|
387 |
$classes = array_merge( $classes, $more );
|
388 |
}
|
|
|
|
|
389 |
|
390 |
if ( $this->get_question()->show_correct_answers() === 'yes' ) {
|
391 |
|
392 |
-
$is_checked = $this->is_checked();
|
393 |
-
$is_true = $this->is_true();
|
394 |
-
|
395 |
if ( $is_true ) {
|
396 |
$classes[] = 'answer-correct';
|
397 |
}
|
@@ -408,6 +407,12 @@ if ( ! class_exists( 'LP_Question_Answer_Option' ) ) {
|
|
408 |
$classes[] = 'answered-wrong';
|
409 |
}
|
410 |
|
|
|
|
|
|
|
|
|
|
|
|
|
411 |
}
|
412 |
|
413 |
// sanitize unwanted classes
|
@@ -449,6 +454,11 @@ if ( ! class_exists( 'LP_Question_Answer_Option' ) ) {
|
|
449 |
*/
|
450 |
public function is_checked() {
|
451 |
if ( false === $this->get_answered() ) {
|
|
|
|
|
|
|
|
|
|
|
452 |
return false;
|
453 |
}
|
454 |
|
53 |
* LP_Question_Answers constructor.
|
54 |
*
|
55 |
* @param LP_Question $question
|
56 |
+
* @param mixed $raw
|
57 |
*
|
58 |
* @param $raw
|
59 |
*/
|
109 |
* Set new option for an answer
|
110 |
*
|
111 |
* @param int|array $id
|
112 |
+
* @param mixed $options
|
113 |
*/
|
114 |
public function set_answer_option( $id, $options = '' ) {
|
115 |
if ( is_array( $id ) && func_num_args() == 1 ) {
|
185 |
* Set answer option by offset.
|
186 |
*
|
187 |
* @param int|string $offset
|
188 |
+
* @param mixed $value
|
189 |
*/
|
190 |
public function offsetSet( $offset, $value ) {
|
191 |
$this->_answers[ $offset ] = $value;
|
324 |
* LP_Question_Answer_Option constructor.
|
325 |
*
|
326 |
* @param LP_Question $question
|
327 |
+
* @param mixed $data
|
328 |
*/
|
329 |
public function __construct( $question, $data ) {
|
330 |
$this->_data = $data;
|
386 |
if ( $more && is_array( $more ) ) {
|
387 |
$classes = array_merge( $classes, $more );
|
388 |
}
|
389 |
+
$is_checked = $this->is_checked();
|
390 |
+
$is_true = $this->is_true();
|
391 |
|
392 |
if ( $this->get_question()->show_correct_answers() === 'yes' ) {
|
393 |
|
|
|
|
|
|
|
394 |
if ( $is_true ) {
|
395 |
$classes[] = 'answer-correct';
|
396 |
}
|
407 |
$classes[] = 'answered-wrong';
|
408 |
}
|
409 |
|
410 |
+
} else if ( learn_press_is_review_questions() ) {
|
411 |
+
if ( $is_checked && $is_true ) {
|
412 |
+
$classes[] = 'answered-correct';
|
413 |
+
} elseif ( $is_checked && ! $is_true ) {
|
414 |
+
$classes[] = 'answered-wrong';
|
415 |
+
}
|
416 |
}
|
417 |
|
418 |
// sanitize unwanted classes
|
454 |
*/
|
455 |
public function is_checked() {
|
456 |
if ( false === $this->get_answered() ) {
|
457 |
+
if ( $this->get_question()->show_correct_answers() === 'yes' && $this->is_true() ) {
|
458 |
+
|
459 |
+
return true;
|
460 |
+
}
|
461 |
+
|
462 |
return false;
|
463 |
}
|
464 |
|
inc/user-item/class-lp-user-item-course.php
CHANGED
@@ -841,8 +841,12 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
|
|
841 |
* @return LP_User_Item_Course
|
842 |
*/
|
843 |
public function get_item_at( $at = 0 ) {
|
844 |
-
$this->read_items();
|
845 |
$item_id = ! empty( $this->_items_by_order[ $at ] ) ? $this->_items_by_order[ $at ] : 0;
|
|
|
|
|
|
|
|
|
846 |
|
847 |
return $this->offsetGet( $item_id );
|
848 |
}
|
841 |
* @return LP_User_Item_Course
|
842 |
*/
|
843 |
public function get_item_at( $at = 0 ) {
|
844 |
+
$items = $this->read_items();
|
845 |
$item_id = ! empty( $this->_items_by_order[ $at ] ) ? $this->_items_by_order[ $at ] : 0;
|
846 |
+
if ( ! $item_id ) {
|
847 |
+
$items = array_values( $items );
|
848 |
+
$item_id = $items[ $at ]->get_id();
|
849 |
+
}
|
850 |
|
851 |
return $this->offsetGet( $item_id );
|
852 |
}
|
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.6.
|
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.6.3
|
8 |
Author URI: http://thimpress.com
|
9 |
Requires at least: 3.8
|
10 |
Tested up to: 5.0.2
|
readme.txt
CHANGED
@@ -3,8 +3,8 @@ Contributors: thimpress, tunnhn, phonglq.foobla, thongta, kendy73, leehld
|
|
3 |
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.
|
7 |
-
Stable tag: 3.2.6.
|
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.6.2 =
|
203 |
~ Fixed cannt add items to course.
|
204 |
|
3 |
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.2.2
|
7 |
+
Stable tag: 3.2.6.3
|
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.6.3 =
|
203 |
+
~ Fixed css conflict with text block of vc.
|
204 |
+
~ Fixed show message 'Out of stock' for course reached limitation users.
|
205 |
+
~ Fixed show checked answers when review quiz.
|
206 |
+
~ Fixed review quiz option does not work properly.
|
207 |
+
~ Fixed update view after removing order's items.
|
208 |
+
|
209 |
= 3.2.6.2 =
|
210 |
~ Fixed cannt add items to course.
|
211 |
|
templates/widgets/featured-courses/default.php
CHANGED
@@ -35,13 +35,13 @@ $instance = $this->instance;
|
|
35 |
|
36 |
<div class="widget-body">
|
37 |
<?php foreach ( $courses as $course_id ) {
|
38 |
-
|
|
|
|
|
39 |
$post = get_post( $course_id );
|
40 |
setup_postdata( $post );
|
41 |
$course = learn_press_get_course( $course_id );
|
42 |
-
|
43 |
?>
|
44 |
-
|
45 |
<div class="course-entry">
|
46 |
|
47 |
<!-- course thumbnail -->
|
35 |
|
36 |
<div class="widget-body">
|
37 |
<?php foreach ( $courses as $course_id ) {
|
38 |
+
if ( empty( $course_id ) ) {
|
39 |
+
continue;
|
40 |
+
}
|
41 |
$post = get_post( $course_id );
|
42 |
setup_postdata( $post );
|
43 |
$course = learn_press_get_course( $course_id );
|
|
|
44 |
?>
|
|
|
45 |
<div class="course-entry">
|
46 |
|
47 |
<!-- course thumbnail -->
|
templates/widgets/popular-courses/default.php
CHANGED
@@ -30,15 +30,13 @@ $instance = $this->instance;
|
|
30 |
|
31 |
<div class="widget-body">
|
32 |
<?php foreach ( $courses as $course_id ) {
|
33 |
-
if (
|
34 |
-
|
35 |
}
|
36 |
$post = get_post( $course_id );
|
37 |
setup_postdata( $post );
|
38 |
$course = learn_press_get_course( $course_id );
|
39 |
-
|
40 |
?>
|
41 |
-
|
42 |
<div class="course-entry">
|
43 |
|
44 |
<!-- course thumbnail -->
|
30 |
|
31 |
<div class="widget-body">
|
32 |
<?php foreach ( $courses as $course_id ) {
|
33 |
+
if ( empty( $course_id ) ) {
|
34 |
+
continue;
|
35 |
}
|
36 |
$post = get_post( $course_id );
|
37 |
setup_postdata( $post );
|
38 |
$course = learn_press_get_course( $course_id );
|
|
|
39 |
?>
|
|
|
40 |
<div class="course-entry">
|
41 |
|
42 |
<!-- course thumbnail -->
|
templates/widgets/recent-courses/default.php
CHANGED
@@ -35,13 +35,13 @@ $instance = $this->instance;
|
|
35 |
|
36 |
<div class="widget-body">
|
37 |
<?php foreach ( $courses as $course_id ) {
|
38 |
-
|
|
|
|
|
39 |
$post = get_post( $course_id );
|
40 |
setup_postdata( $post );
|
41 |
$course = learn_press_get_course( $course_id );
|
42 |
-
|
43 |
?>
|
44 |
-
|
45 |
<div class="course-entry">
|
46 |
|
47 |
<!-- course thumbnail -->
|
35 |
|
36 |
<div class="widget-body">
|
37 |
<?php foreach ( $courses as $course_id ) {
|
38 |
+
if ( empty( $course_id ) ) {
|
39 |
+
continue;
|
40 |
+
}
|
41 |
$post = get_post( $course_id );
|
42 |
setup_postdata( $post );
|
43 |
$course = learn_press_get_course( $course_id );
|
|
|
44 |
?>
|
|
|
45 |
<div class="course-entry">
|
46 |
|
47 |
<!-- course thumbnail -->
|