LearnPress – WordPress LMS Plugin - Version 3.0.4

Version Description

~ Improved: action when clicking to close upgrade notice ~ Fixed: can not add course from other users to order ~ Fixed: lost quiz data after upgrading ~ Fixed: user can view lesson/quiz with single permalink ~ Fixed: can not view lesson ~ Fixed: notices in admin orders ~ Fixed: external buy this course redirect to home page ~ Fixed: remaining time message with course duration is zero ~ Fixed: hidden sections action ajax admin course editor ~ Fixed: admin can not add course to order from other users ~ More...

Download this release

Release Info

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

Code changes from version 3.0.3 to 3.0.4

Files changed (41) hide show
  1. assets/css/learnpress.css +1 -1
  2. assets/js/admin/admin.js +1 -1
  3. assets/js/admin/modal-search-items.js +5 -1
  4. assets/js/frontend/course.js +9 -1
  5. assets/scss/frontend/_curriculum.scss +1 -2
  6. inc/admin/class-lp-modal-search-items.php +3 -1
  7. inc/admin/class-lp-updater.php +1 -1
  8. inc/admin/editor/class-lp-admin-editor-course.php +1 -1
  9. inc/admin/lp-admin-functions.php +28 -8
  10. inc/admin/views/html-admin-notice-templates.php +1 -1
  11. inc/admin/views/modal-search-items.php +1 -1
  12. inc/admin/views/updates/html-upgrade-message-3.0.0.php +2 -2
  13. inc/class-lp-ajax.php +21 -0
  14. inc/class-lp-install.php +3 -2
  15. inc/class-lp-page-controller.php +26 -11
  16. inc/class-lp-settings.php +10 -3
  17. inc/course/abstract-course.php +7 -3
  18. inc/curds/class-lp-course-curd.php +0 -6
  19. inc/curds/class-lp-order-curd.php +7 -8
  20. inc/curds/class-lp-question-curd.php +6 -2
  21. inc/custom-post-types/order.php +4 -3
  22. inc/lp-constants.php +1 -1
  23. inc/lp-core-functions.php +19 -0
  24. inc/lp-template-functions.php +2 -2
  25. inc/order/class-lp-order.php +53 -35
  26. inc/question/class-lp-question-answers.php +1 -1
  27. inc/updates/learnpress-update-2.1.1.php +4 -3
  28. inc/updates/learnpress-update-3.0.4.php +82 -0
  29. inc/user-item/class-lp-user-item-quiz.php +6 -3
  30. inc/user-item/class-lp-user-item.php +9 -8
  31. inc/user/abstract-lp-user.php +1 -0
  32. inc/user/class-lp-profile-tabs.php +1 -1
  33. inc/user/lp-user-functions.php +2 -0
  34. learnpress.php +1 -1
  35. readme.txt +14 -1
  36. templates/profile/tabs.php +13 -4
  37. templates/profile/tabs/orders/list.php +1 -1
  38. templates/profile/tabs/quizzes.php +1 -3
  39. templates/single-course/buttons/external-link.php +5 -2
  40. templates/single-course/remaining-time.php +6 -6
  41. templates/single-course/section/content-item.php +12 -4
assets/css/learnpress.css CHANGED
@@ -621,7 +621,7 @@
621
clear: both;
622
display: block;
623
content: ''; }
624
- .lp-single-course .course-author .list-course-instructors {
625
clear: both;
626
padding-top: 20px; }
627
621
clear: both;
622
display: block;
623
content: ''; }
624
+ .lp-single-course .course-author .course-instructor-item {
625
clear: both;
626
padding-top: 20px; }
627
assets/js/admin/admin.js CHANGED
@@ -289,13 +289,13 @@
289
function hideUpgradeMessage(e) {
290
e.preventDefault();
291
var $btn = $(this);
292
$.post({
293
url: '',
294
data: {
295
'lp-hide-upgrade-message': 'yes'
296
},
297
success: function (res) {
298
- $btn.closest('.lp-upgrade-notice').fadeOut();
299
}
300
});
301
}
289
function hideUpgradeMessage(e) {
290
e.preventDefault();
291
var $btn = $(this);
292
+ $btn.closest('.lp-upgrade-notice').fadeOut();
293
$.post({
294
url: '',
295
data: {
296
'lp-hide-upgrade-message': 'yes'
297
},
298
success: function (res) {
299
}
300
});
301
}
assets/js/admin/modal-search-items.js CHANGED
@@ -31,6 +31,7 @@
31
},
32
search: _.debounce(function (term) {
33
var that = this;
34
Vue.http.post(
35
window.location.href, {
36
type: this.postType,
@@ -111,13 +112,16 @@
111
term: '',
112
postType: '',
113
callbacks: {},
114
- exclude: ''
115
},
116
methods: {
117
open: function (options) {
118
_.each(options.data, function (v, k) {
119
this[k] = v;
120
}, this);
121
this.callbacks = options.callbacks;
122
this.focusSearch();
123
},
31
},
32
search: _.debounce(function (term) {
33
var that = this;
34
+ console.log(this)
35
Vue.http.post(
36
window.location.href, {
37
type: this.postType,
112
term: '',
113
postType: '',
114
callbacks: {},
115
+ exclude: '',
116
+ context: ''
117
},
118
methods: {
119
open: function (options) {
120
+ console.log(options)
121
_.each(options.data, function (v, k) {
122
this[k] = v;
123
}, this);
124
+
125
this.callbacks = options.callbacks;
126
this.focusSearch();
127
},
assets/js/frontend/course.js CHANGED
@@ -540,7 +540,15 @@
540
541
$(document).ready(function () {
542
$(document).ready(function () {
543
- new LP_Course({})
544
});
545
});
546
})
540
541
$(document).ready(function () {
542
$(document).ready(function () {
543
+ new LP_Course({});
544
+
545
+ $(this).on('submit', 'form[name="course-external-link"]', function () {
546
+ var redirect = $(this).attr('action');
547
+ if (redirect) {
548
+ window.location.href = redirect;
549
+ return false;
550
+ }
551
+ })
552
});
553
});
554
})
assets/scss/frontend/_curriculum.scss CHANGED
@@ -30,8 +30,7 @@
30
&:after {
31
@include clear-fix();
32
}
33
-
34
- .list-course-instructors {
35
clear: both;
36
padding-top: 20px;
37
}
30
&:after {
31
@include clear-fix();
32
}
33
+ .course-instructor-item {
34
clear: both;
35
padding-top: 20px;
36
}
inc/admin/class-lp-modal-search-items.php CHANGED
@@ -133,7 +133,9 @@ if ( ! class_exists( 'LP_Modal_Search_Items' ) ) {
133
'offset' => ( $paged - 1 ) * $this->_options['limit']
134
);
135
136
- $args['author'] = get_post_field( 'post_author', $context_id );
137
138
if ( $term ) {
139
$args['s'] = $term;
133
'offset' => ( $paged - 1 ) * $this->_options['limit']
134
);
135
136
+ if ( $context_id = apply_filters( 'learn-press/modal-search-items/context-id', $context_id, $context ) ) {
137
+ $args['author'] = get_post_field( 'post_author', $context_id );
138
+ }
139
140
if ( $term ) {
141
$args['s'] = $term;
inc/admin/class-lp-updater.php CHANGED
@@ -32,7 +32,7 @@ class LP_Updater {
32
return;
33
}
34
echo '<div>';
35
- ob_start();
36
try {
37
LP_Debug::startTransaction();
38
foreach ( $this->get_update_files() as $version => $file ) {
32
return;
33
}
34
echo '<div>';
35
+ //ob_start();
36
try {
37
LP_Debug::startTransaction();
38
foreach ( $this->get_update_files() as $version => $file ) {
inc/admin/editor/class-lp-admin-editor-course.php CHANGED
@@ -86,7 +86,7 @@ class LP_Admin_Editor_Course extends LP_Admin_Editor {
86
/**
87
* @param array $args
88
*/
89
- public function hide_sections( $args ) {
90
// get hidden sections id
91
$hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
92
// update course post meta
86
/**
87
* @param array $args
88
*/
89
+ public function hidden_sections( $args ) {
90
// get hidden sections id
91
$hidden = ! empty( $args['hidden'] ) ? $args['hidden'] : false;
92
// update course post meta
inc/admin/lp-admin-functions.php CHANGED
@@ -137,16 +137,16 @@ function learn_press_admin_view_content( $name, $args = array() ) {
137
* Find a full path of a view and display the content in admin
138
*
139
* @param $name
140
- * @param array $args
141
* @param bool|false $include_once
142
* @param bool
143
*
144
* @return bool
145
*/
146
function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
147
- $view = learn_press_get_admin_view( $name, ! empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
148
149
- if ( file_exists( $view ) ) {
150
ob_start();
151
// extract parameters as local variables if passed
152
is_array( $args ) && extract( $args );
@@ -173,7 +173,7 @@ function learn_press_admin_view( $name, $args = array(), $include_once = false,
173
*
174
* @param $name
175
* @param bool|false $selected
176
- * @param array $args
177
*
178
* @return mixed|string
179
*/
@@ -234,7 +234,7 @@ function learn_press_pages_dropdown( $name, $selected = false, $args = array() )
234
$output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
235
}
236
237
- $output = str_replace('<option class="level-0" value="00000">#0 (no title)</option>', '', $output);
238
239
if ( $selected && get_post_status( $selected ) !== 'publish' ) {
240
$selected = 0;
@@ -1676,9 +1676,9 @@ if ( ! function_exists( 'learn_press_duplicate_post' ) ) {
1676
*
1677
* @since 3.0.0
1678
*
1679
- * @param null $post_id
1680
* @param array $args
1681
- * @param bool $meta
1682
*
1683
* @return bool|mixed
1684
*/
@@ -2180,4 +2180,24 @@ function learn_press_touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $mult
2180
$cur_timeunit = 'cur_' . $timeunit;
2181
echo '<input type="hidden" id="' . $cur_timeunit . '" name="' . $cur_timeunit . '" value="' . $curr . '" />' . "\n";
2182
}
2183
- }
137
* Find a full path of a view and display the content in admin
138
*
139
* @param $name
140
+ * @param array $args
141
* @param bool|false $include_once
142
* @param bool
143
*
144
* @return bool
145
*/
146
function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
147
+ $view = learn_press_get_admin_view( $name, ! empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
148
149
+ if ( file_exists( $view ) ) {
150
ob_start();
151
// extract parameters as local variables if passed
152
is_array( $args ) && extract( $args );
173
*
174
* @param $name
175
* @param bool|false $selected
176
+ * @param array $args
177
*
178
* @return mixed|string
179
*/
234
$output = preg_replace( '!(<option class=".*" value="[0-9]+".*>.*</option>)!', $before_output . "\n$1", $output, 1 );
235
}
236
237
+ $output = str_replace( '<option class="level-0" value="00000">#0 (no title)</option>', '', $output );
238
239
if ( $selected && get_post_status( $selected ) !== 'publish' ) {
240
$selected = 0;
1676
*
1677
* @since 3.0.0
1678
*
1679
+ * @param null $post_id
1680
* @param array $args
1681
+ * @param bool $meta
1682
*
1683
* @return bool|mixed
1684
*/
2180
$cur_timeunit = 'cur_' . $timeunit;
2181
echo '<input type="hidden" id="' . $cur_timeunit . '" name="' . $cur_timeunit . '" value="' . $curr . '" />' . "\n";
2182
}
2183
+ }
2184
+
2185
+ /**
2186
+ * Filter to modal search items to void filter the posts by author.
2187
+ *
2188
+ * @since 3.0.4
2189
+ *
2190
+ * @param int|string $context_id
2191
+ * @param string $context
2192
+ *
2193
+ * @return bool|int|string
2194
+ */
2195
+ function learn_press_modal_search_items_context( $context_id, $context ) {
2196
+ if ( 'order-items' === $context ) {
2197
+ $context_id = false;
2198
+ }
2199
+
2200
+ return $context_id;
2201
+ }
2202
+
2203
+ add_filter( 'learn-press/modal-search-items/context-id', 'learn_press_modal_search_items_context', 10, 2 );
inc/admin/views/html-admin-notice-templates.php CHANGED
@@ -27,7 +27,7 @@ $theme_name = implode( ' & ', $theme_name );
27
28
$readmore = 'https://thimpress.com/knowledge-base/outdated-template-fix/';
29
?>
30
- <div id="message" class="learn-press-message notice-warning">
31
<p><?php printf( wp_kses( __( 'There is a new update of LearnPress. You may need to update your theme <strong>(%s)</strong> to avoid outdated template files.', 'learnpress' ), array( 'strong' => array() ) ), $theme_name ); ?></p>
32
<p class="outdated-readmore-link"><?php echo sprintf( wp_kses( __( 'This is not a bug, don\'t worry. Read more about Outdated template files notice <a href="%s" target="_blank">here</a>.', 'learnpress' ), array(
33
'a' => array(
27
28
$readmore = 'https://thimpress.com/knowledge-base/outdated-template-fix/';
29
?>
30
+ <div id="message" class="learn-press-message notice-warning notice">
31
<p><?php printf( wp_kses( __( 'There is a new update of LearnPress. You may need to update your theme <strong>(%s)</strong> to avoid outdated template files.', 'learnpress' ), array( 'strong' => array() ) ), $theme_name ); ?></p>
32
<p class="outdated-readmore-link"><?php echo sprintf( wp_kses( __( 'This is not a bug, don\'t worry. Read more about Outdated template files notice <a href="%s" target="_blank">here</a>.', 'learnpress' ), array(
33
'a' => array(
inc/admin/views/modal-search-items.php CHANGED
@@ -25,7 +25,7 @@
25
</div>
26
</script>
27
<div id="vue-modal-search-items" style="position: relative;z-index: 10000;">
28
- <learn-press-modal-search-items v-if="show" :post-type="postType" :term="term" :contex="context"
29
:context-id="contextId" :show="show" :callbacks="callbacks"
30
:exclude="exclude"
31
v-on:close="close">
25
</div>
26
</script>
27
<div id="vue-modal-search-items" style="position: relative;z-index: 10000;">
28
+ <learn-press-modal-search-items v-if="show" :post-type="postType" :term="term" :context="context"
29
:context-id="contextId" :show="show" :callbacks="callbacks"
30
:exclude="exclude"
31
v-on:close="close">
inc/admin/views/updates/html-upgrade-message-3.0.0.php CHANGED
@@ -11,7 +11,7 @@ defined( 'ABSPATH' ) or die();
11
12
?>
13
<div class="notice notice-warning lp-notice lp-upgrade-notice">
14
- <h4><?php _e( 'Welcome to LearnPress 3.0.0', 'learnpress' ); ?></h4>
15
<p><?php _e( 'This is a <strong>BIG UPDATE</strong> and it allows you to do so much more!', 'learnpress' ); ?></p>
16
<p><?php _e( 'If there\'s any issue, please be sure to backup your site, update your theme, contact supporter.', 'learnpres' ); ?></p>
17
<p>
@@ -21,5 +21,5 @@ defined( 'ABSPATH' ) or die();
21
<a class="button" href="https://thimpress.com/help/"
22
target="_blank"><?php _e( 'Get support now', 'learnpress' ); ?></a>
23
</p>
24
- <a class="close-notice" href=""><?php _e('Got it!', 'learnpress');?></a>
25
</div>
11
12
?>
13
<div class="notice notice-warning lp-notice lp-upgrade-notice">
14
+ <h4><?php printf( __( 'Welcome to LearnPress %s', 'learnpress' ), LEARNPRESS_VERSION ); ?></h4>
15
<p><?php _e( 'This is a <strong>BIG UPDATE</strong> and it allows you to do so much more!', 'learnpress' ); ?></p>
16
<p><?php _e( 'If there\'s any issue, please be sure to backup your site, update your theme, contact supporter.', 'learnpres' ); ?></p>
17
<p>
21
<a class="button" href="https://thimpress.com/help/"
22
target="_blank"><?php _e( 'Get support now', 'learnpress' ); ?></a>
23
</p>
24
+ <a class="close-notice" href=""><?php _e( 'Got it!', 'learnpress' ); ?></a>
25
</div>
inc/class-lp-ajax.php CHANGED
@@ -53,6 +53,7 @@ if ( ! class_exists( 'LP_AJAX' ) ) {
53
'complete-lesson',
54
'finish-course',
55
'retake-course',
56
//'register-user:nopriv',
57
//'login-user:nopriv'
58
);
@@ -82,6 +83,26 @@ if ( ! class_exists( 'LP_AJAX' ) ) {
82
//LP_Request::register_ajax( 'recover-order', array( __CLASS__, 'recover_order' ) );
83
}
84
85
public static function register_user() {
86
87
if ( ! get_option( 'users_can_register' ) ) {
53
'complete-lesson',
54
'finish-course',
55
'retake-course',
56
+ 'external-link'
57
//'register-user:nopriv',
58
//'login-user:nopriv'
59
);
83
//LP_Request::register_ajax( 'recover-order', array( __CLASS__, 'recover_order' ) );
84
}
85
86
+ public static function external_link() {
87
+ $nonce = LP_Request::get( 'nonce' );
88
+ $id = LP_Request::get( 'id' );
89
+
90
+ if ( ! $course = learn_press_get_course( $id ) ) {
91
+ return;
92
+ }
93
+
94
+ $link = $course->get_external_link();
95
+
96
+ if ( ! wp_verify_nonce( $nonce, 'external-link-' . $link ) ) {
97
+ return;
98
+ }
99
+
100
+ if ( apply_filters( 'learn-press/course-redirect-external-link', $id ) ) {
101
+ wp_redirect( $link );
102
+ exit();
103
+ }
104
+ }
105
+
106
public static function register_user() {
107
108
if ( ! get_option( 'users_can_register' ) ) {
inc/class-lp-install.php CHANGED
@@ -51,6 +51,7 @@ if ( ! function_exists( 'LP_Install' ) ) {
51
52
//add_action( 'learn_press_activate', array( __CLASS__, 'install' ) );
53
54
return;
55
add_action( 'admin_init', array( __CLASS__, 'include_update' ), - 10 );
56
add_action( 'admin_init', array( __CLASS__, 'update_from_09' ), 5 );
@@ -105,7 +106,7 @@ if ( ! function_exists( 'LP_Install' ) ) {
105
$db_version = get_option( 'learnpress_db_version' );
106
107
// Check latest version with the value updated in db
108
- if ( !$db_version || version_compare( $db_version, LEARNPRESS_VERSION, '=' ) ) {
109
return;
110
}
111
@@ -130,7 +131,7 @@ if ( ! function_exists( 'LP_Install' ) ) {
130
self::_delete_transients();
131
self::_create_log_path();
132
///self::_create_pages();
133
-
134
$current_version = get_option( 'learnpress_version', null );
135
$current_db_version = get_option( 'learnpress_db_version', null );
136
51
52
//add_action( 'learn_press_activate', array( __CLASS__, 'install' ) );
53
54
+
55
return;
56
add_action( 'admin_init', array( __CLASS__, 'include_update' ), - 10 );
57
add_action( 'admin_init', array( __CLASS__, 'update_from_09' ), 5 );
106
$db_version = get_option( 'learnpress_db_version' );
107
108
// Check latest version with the value updated in db
109
+ if ( !$db_version || version_compare( $db_version, LEARNPRESS_VERSION, '>=' ) ) {
110
return;
111
}
112
131
self::_delete_transients();
132
self::_create_log_path();
133
///self::_create_pages();
134
+ delete_transient( 'lp_upgraded_30' );
135
$current_version = get_option( 'learnpress_version', null );
136
$current_db_version = get_option( 'learnpress_db_version', null );
137
inc/class-lp-page-controller.php CHANGED
@@ -273,6 +273,7 @@ class LP_Page_Controller {
273
274
if ( $file ) {
275
$_template = locate_template( array_unique( $find ) );
276
if ( ! $_template && ! in_array( $file, array( 'single-course.php', 'archive-course.php' ) ) ) {
277
$_template = learn_press_plugin_path( 'templates/' ) . $file;
278
}
@@ -477,7 +478,7 @@ class LP_Page_Controller {
477
remove_filter( 'the_content', 'wpautop' );
478
}
479
480
- $content = wpautop($content);
481
$content = do_shortcode( $content );
482
483
if ( $has_filter ) {
@@ -493,14 +494,14 @@ class LP_Page_Controller {
493
$wp_query->post->post_title = single_term_title( '', false );
494
}
495
496
- $wp_query->post->post_content = $content;
497
- $wp_query->posts = array( $wp_query->post );
498
499
- if( is_post_type_archive( LP_COURSE_CPT ) || LEARNPRESS_IS_CATEGORY ) {
500
- $wp_query->is_page = false;
501
- $wp_query->is_archive = true;
502
- $wp_query->is_category = true;
503
- $wp_query->is_single = false;
504
} else {
505
$wp_query->found_posts = 1;
506
$wp_query->is_single = true;
@@ -530,6 +531,7 @@ class LP_Page_Controller {
530
$wp_query->is_post_type_archive = false;
531
}
532
}
533
return $template;
534
}
535
@@ -546,9 +548,10 @@ class LP_Page_Controller {
546
return $content;
547
}
548
549
- if ( false !== ( $_content = wp_cache_get( 'course-' . get_the_ID(), 'course-content' ) ) ) {
550
- return $_content;
551
- }
552
553
remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
554
add_filter( 'the_content', 'wpautop' );
@@ -590,6 +593,18 @@ class LP_Page_Controller {
590
if ( ! $q->is_main_query() || is_admin() ) {
591
return $q;
592
}
593
remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
594
595
$this->_queried_object = ! empty( $q->queried_object_id ) ? $q->queried_object : false;
273
274
if ( $file ) {
275
$_template = locate_template( array_unique( $find ) );
276
+
277
if ( ! $_template && ! in_array( $file, array( 'single-course.php', 'archive-course.php' ) ) ) {
278
$_template = learn_press_plugin_path( 'templates/' ) . $file;
279
}
478
remove_filter( 'the_content', 'wpautop' );
479
}
480
481
+ $content = wpautop( $content );
482
$content = do_shortcode( $content );
483
484
if ( $has_filter ) {
494
$wp_query->post->post_title = single_term_title( '', false );
495
}
496
497
+ $wp_query->post->post_content = $content;
498
+ $wp_query->posts = array( $wp_query->post );
499
500
+ if ( is_post_type_archive( LP_COURSE_CPT ) || LEARNPRESS_IS_CATEGORY ) {
501
+ $wp_query->is_page = false;
502
+ $wp_query->is_archive = true;
503
+ $wp_query->is_category = true;
504
+ $wp_query->is_single = false;
505
} else {
506
$wp_query->found_posts = 1;
507
$wp_query->is_single = true;
531
$wp_query->is_post_type_archive = false;
532
}
533
}
534
+
535
return $template;
536
}
537
548
return $content;
549
}
550
551
+ #@NOTE: make sure current page is not lesson or quiz before return cache content of single course page
552
+ // if ( function_exists( 'learn_press_content_single_course' ) && false !== ( $_content = wp_cache_get( 'course-' . get_the_ID(), 'course-content' ) ) ) {
553
+ // return $_content;
554
+ // }
555
556
remove_filter( 'the_content', array( $this, 'single_content' ), $this->_filter_content_priority );
557
add_filter( 'the_content', 'wpautop' );
593
if ( ! $q->is_main_query() || is_admin() ) {
594
return $q;
595
}
596
+
597
+ // Handle 404 if user are viewing course item directly.
598
+ // Example: http://example.com/lesson/sample-lesson
599
+ $course_support_items = learn_press_get_course_item_types();
600
+
601
+ if ( isset($q->query_vars['post_type']) && in_array( $q->query_vars['post_type'], $course_support_items ) ) {
602
+ learn_press_404_page();
603
+ $q->set( 'post_type', '__unknown' );
604
+
605
+ return $q;
606
+ }
607
+
608
remove_action( 'pre_get_posts', array( $this, 'pre_get_posts' ), 10 );
609
610
$this->_queried_object = ! empty( $q->queried_object_id ) ? $q->queried_object : false;
inc/class-lp-settings.php CHANGED
@@ -51,6 +51,7 @@ class LP_Settings {
51
settype( $data, 'array' );
52
$this->_options = $data;
53
}
54
}
55
56
/**
@@ -72,9 +73,11 @@ class LP_Settings {
72
*/
73
protected function _load_options( $force = false ) {
74
$_options = wp_load_alloptions();
75
- foreach ( $_options as $k => $v ) {
76
- $this->_options[ $k ] = maybe_unserialize( $v );
77
- }
78
79
// if ( ( false === ( $_options = wp_cache_get( 'options', 'lp-options' ) ) ) || $force ) {
80
// global $wpdb;
@@ -114,6 +117,7 @@ class LP_Settings {
114
$current_var = array_shift( $var );
115
if ( is_object( $obj ) ) {
116
if ( isset( $obj->{$current_var} ) ) {
117
if ( count( $var ) ) {
118
$this->_set_option( $obj->{$current_var}, join( '.', $var ), $value );
119
} else {
@@ -124,6 +128,7 @@ class LP_Settings {
124
}
125
} else {
126
if ( isset( $obj[ $current_var ] ) ) {
127
if ( count( $var ) ) {
128
$this->_set_option( $obj[ $current_var ], join( '.', $var ), $value );
129
} else {
@@ -172,6 +177,7 @@ class LP_Settings {
172
$current_var = array_shift( $var );
173
if ( is_object( $obj ) ) {
174
if ( isset( $obj->{$current_var} ) ) {
175
if ( count( $var ) ) {
176
return $this->_get_option( $obj->{$current_var}, join( '.', $var ), $default );
177
} else {
@@ -182,6 +188,7 @@ class LP_Settings {
182
}
183
} else {
184
if ( isset( $obj[ $current_var ] ) ) {
185
if ( count( $var ) ) {
186
return $this->_get_option( $obj[ $current_var ], join( '.', $var ), $default );
187
} else {
51
settype( $data, 'array' );
52
$this->_options = $data;
53
}
54
+
55
}
56
57
/**
73
*/
74
protected function _load_options( $force = false ) {
75
$_options = wp_load_alloptions();
76
+ // foreach ( $_options as $k => $v ) {
77
+ // $this->_options[ $k ] = maybe_unserialize( $v );
78
+ // }
79
+
80
+ $this->_options = $_options;
81
82
// if ( ( false === ( $_options = wp_cache_get( 'options', 'lp-options' ) ) ) || $force ) {
83
// global $wpdb;
117
$current_var = array_shift( $var );
118
if ( is_object( $obj ) ) {
119
if ( isset( $obj->{$current_var} ) ) {
120
+ $obj->{$current_var} = maybe_unserialize($obj->{$current_var});
121
if ( count( $var ) ) {
122
$this->_set_option( $obj->{$current_var}, join( '.', $var ), $value );
123
} else {
128
}
129
} else {
130
if ( isset( $obj[ $current_var ] ) ) {
131
+ $obj[ $current_var ] = maybe_unserialize($obj[ $current_var ]);
132
if ( count( $var ) ) {
133
$this->_set_option( $obj[ $current_var ], join( '.', $var ), $value );
134
} else {
177
$current_var = array_shift( $var );
178
if ( is_object( $obj ) ) {
179
if ( isset( $obj->{$current_var} ) ) {
180
+ $obj->{$current_var} = maybe_unserialize($obj->{$current_var});
181
if ( count( $var ) ) {
182
return $this->_get_option( $obj->{$current_var}, join( '.', $var ), $default );
183
} else {
188
}
189
} else {
190
if ( isset( $obj[ $current_var ] ) ) {
191
+ $obj[ $current_var ] = maybe_unserialize($obj[ $current_var ]);
192
if ( count( $var ) ) {
193
return $this->_get_option( $obj[ $current_var ], join( '.', $var ), $default );
194
} else {
inc/course/abstract-course.php CHANGED
@@ -1659,9 +1659,11 @@ if ( ! function_exists( 'LP_Abstract_Course' ) ) {
1659
$course_info = $user->get_course_info( $this->get_id() );
1660
$start_time = array_key_exists( 'start_time', $args ) ? $args['start_time'] : ( is_array( $course_info ) && array_key_exists( 'start', $course_info ) ? intval( strtotime( $course_info['start'] ) ) : 0 );
1661
if ( $duration == 0 ) {
1662
- $duration = DAY_IN_SECONDS * 365 * 100;
1663
}
1664
- $expired = $start_time + $duration;
1665
1666
return apply_filters( 'learn_press_user_course_expired_time', $expired, $user_id, $this->get_id() );
1667
}
@@ -1680,7 +1682,9 @@ if ( ! function_exists( 'LP_Abstract_Course' ) ) {
1680
$user_id = get_current_user_id();
1681
}
1682
1683
- return apply_filters( 'learn_press_user_course_expired', $this->get_user_expired_time( $user_id, $args ) - current_time( 'timestamp' ) );
1684
}
1685
1686
/**
1659
$course_info = $user->get_course_info( $this->get_id() );
1660
$start_time = array_key_exists( 'start_time', $args ) ? $args['start_time'] : ( is_array( $course_info ) && array_key_exists( 'start', $course_info ) ? intval( strtotime( $course_info['start'] ) ) : 0 );
1661
if ( $duration == 0 ) {
1662
+ //$duration = DAY_IN_SECONDS * 365 * 100;
1663
+ $expired = false;
1664
+ } else {
1665
+ $expired = $start_time + $duration;
1666
}
1667
1668
return apply_filters( 'learn_press_user_course_expired_time', $expired, $user_id, $this->get_id() );
1669
}
1682
$user_id = get_current_user_id();
1683
}
1684
1685
+ $expired = $this->get_user_expired_time( $user_id, $args );
1686
+
1687
+ return apply_filters( 'learn_press_user_course_expired', $expired !== false ? ( $expired - current_time( 'timestamp' ) ) : false );
1688
}
1689
1690
/**
inc/curds/class-lp-course-curd.php CHANGED
@@ -216,11 +216,8 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
216
*/
217
public function read_course_curriculum( $course_id ) {
218
global $wpdb;
219
- LP_Debug::log_function( __CLASS__ . '::' . __FUNCTION__ );
220
221
if ( get_post_type( $course_id ) != LP_COURSE_CPT ) {
222
- LP_Debug::log_function( __CLASS__ . '::' . __FUNCTION__ );
223
-
224
return false;
225
}
226
@@ -229,8 +226,6 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
229
* then ignore that course.
230
*/
231
if ( wp_cache_get( 'course-' . $course_id, 'lp-course-curriculum' ) ) {
232
- LP_Debug::log_function( __CLASS__ . '::' . __FUNCTION__ );
233
-
234
return false;
235
}
236
@@ -357,7 +352,6 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
357
$quiz_factory = new LP_Quiz_CURD();
358
$quiz_factory->load_questions( $quiz_ids );
359
}
360
- LP_Debug::log_function( __CLASS__ . '::' . __FUNCTION__ );
361
362
return true;
363
}
216
*/
217
public function read_course_curriculum( $course_id ) {
218
global $wpdb;
219
220
if ( get_post_type( $course_id ) != LP_COURSE_CPT ) {
221
return false;
222
}
223
226
* then ignore that course.
227
*/
228
if ( wp_cache_get( 'course-' . $course_id, 'lp-course-curriculum' ) ) {
229
return false;
230
}
231
352
$quiz_factory = new LP_Quiz_CURD();
353
$quiz_factory->load_questions( $quiz_ids );
354
}
355
356
return true;
357
}
inc/curds/class-lp-order-curd.php CHANGED
@@ -25,7 +25,7 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
25
public function create( &$order ) {
26
27
$order->set_order_date( current_time( 'timestamp' ) );
28
- $order->set_order_key( learn_press_generate_order_key() );
29
30
$order_data = array(
31
'post_author' => '1',
@@ -34,8 +34,8 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
34
'post_status' => $order->get_order_status(),
35
'ping_status' => 'closed',
36
'post_title' => $order->get_title(),
37
- 'post_date' => $order->get_order_date()->toSql( true ),
38
- 'post_date_gmt' => $order->get_order_date()->toSql( false ),
39
'post_excerpt' => $order->get_customer_note()
40
);
41
@@ -153,8 +153,8 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
153
}
154
155
$post_data = array(
156
- 'post_date' => $order->get_order_date()->toSql(),
157
- 'post_date_gmt' => $order->get_order_date()->toSql( false ),
158
'post_status' => 'lp-' . $status,
159
'post_parent' => $order->get_parent_id(),
160
//'post_excerpt' => $this->get_post_excerpt( $order ),
@@ -471,7 +471,7 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
471
* Recover an order checked out by Guest for an user.
472
*
473
* @param string $order_key
474
- * @param int $user_id
475
*
476
* @return bool|LP_Order|WP_Error
477
*/
@@ -502,8 +502,7 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
502
503
// Trigger action
504
do_action( 'learn-press/order/recovered-successful', $order->get_id(), $user_id );
505
- }
506
- catch ( Exception $ex ) {
507
return new WP_Error( $ex->getCode(), $ex->getMessage() );
508
}
509
25
public function create( &$order ) {
26
27
$order->set_order_date( current_time( 'timestamp' ) );
28
+ $order->set_order_key( learn_press_generate_order_key() );
29
30
$order_data = array(
31
'post_author' => '1',
34
'post_status' => $order->get_order_status(),
35
'ping_status' => 'closed',
36
'post_title' => $order->get_title(),
37
+ 'post_date' => $order->get_order_date( 'edit' )->toSql( true ),
38
+ 'post_date_gmt' => $order->get_order_date( 'edit' )->toSql( false ),
39
'post_excerpt' => $order->get_customer_note()
40
);
41
153
}
154
155
$post_data = array(
156
+ 'post_date' => $order->get_order_date( 'edit' )->toSql(),
157
+ 'post_date_gmt' => $order->get_order_date( 'edit' )->toSql( false ),
158
'post_status' => 'lp-' . $status,
159
'post_parent' => $order->get_parent_id(),
160
//'post_excerpt' => $this->get_post_excerpt( $order ),
471
* Recover an order checked out by Guest for an user.
472
*
473
* @param string $order_key
474
+ * @param int $user_id
475
*
476
* @return bool|LP_Order|WP_Error
477
*/
502
503
// Trigger action
504
do_action( 'learn-press/order/recovered-successful', $order->get_id(), $user_id );
505
+ } catch ( Exception $ex ) {
506
return new WP_Error( $ex->getCode(), $ex->getMessage() );
507
}
508
inc/curds/class-lp-question-curd.php CHANGED
@@ -201,7 +201,7 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
201
/**
202
* Duplicate answer question.
203
*
204
- * @param $question_id | origin question
205
* @param $new_question_id | new question
206
*/
207
public function duplicate_answer( $question_id, $new_question_id ) {
@@ -754,7 +754,7 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
754
* @since 3.0.0
755
*
756
* @param string $question_type
757
- * @param array $args
758
*
759
* @return array|bool
760
*/
@@ -839,8 +839,12 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
839
return $this->get_error( 'QUESTION_NOT_EXISTS' );
840
}
841
842
global $wpdb;
843
$wpdb->delete( $wpdb->learnpress_question_answers, array( 'question_id' => $question_id ) );
844
}
845
846
/**
201
/**
202
* Duplicate answer question.
203
*
204
+ * @param $question_id | origin question
205
* @param $new_question_id | new question
206
*/
207
public function duplicate_answer( $question_id, $new_question_id ) {
754
* @since 3.0.0
755
*
756
* @param string $question_type
757
+ * @param array $args
758
*
759
* @return array|bool
760
*/
839
return $this->get_error( 'QUESTION_NOT_EXISTS' );
840
}
841
842
+ do_action( 'learn-press/before-clear-question', $question_id );
843
+
844
global $wpdb;
845
$wpdb->delete( $wpdb->learnpress_question_answers, array( 'question_id' => $question_id ) );
846
+
847
+ return true;
848
}
849
850
/**
inc/custom-post-types/order.php CHANGED
@@ -739,8 +739,7 @@ if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
739
$the_order = learn_press_get_order( $post->ID );
740
switch ( $column ) {
741
case 'order_student':
742
- if ( $user_ids = $the_order->get_data( 'user_id' ) ) {
743
- settype( $user_ids, 'array' );
744
$outputs = array();
745
foreach ( $user_ids as $user_id ) {
746
if ( get_user_by( 'id', $user_id ) ) {
@@ -753,7 +752,9 @@ if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
753
$user->get_data( 'user_email' )
754
);
755
} else {
756
- $outputs[] = $the_order->get_customer_name();
757
}
758
}
759
echo join( ', ', $outputs );
739
$the_order = learn_press_get_order( $post->ID );
740
switch ( $column ) {
741
case 'order_student':
742
+ if ( $user_ids = $the_order->get_users() ) {
743
$outputs = array();
744
foreach ( $user_ids as $user_id ) {
745
if ( get_user_by( 'id', $user_id ) ) {
752
$user->get_data( 'user_email' )
753
);
754
} else {
755
+ if ( sizeof( $user_ids ) == 1 ) {
756
+ $outputs[] = $the_order->get_customer_name();
757
+ }
758
}
759
}
760
echo join( ', ', $outputs );
inc/lp-constants.php CHANGED
@@ -4,7 +4,7 @@
4
*/
5
$upload_dir = wp_upload_dir();
6
// version
7
- define( 'LEARNPRESS_VERSION', '3.0.3' );
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.0.4' );
8
9
define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
inc/lp-core-functions.php CHANGED
@@ -3109,4 +3109,23 @@ function learn_press_sort_list_by_priority_callback( $a, $b ) {
3109
}
3110
3111
return ( $a_priority < $b_priority ) ? - 1 : 1;
3112
}
3109
}
3110
3111
return ( $a_priority < $b_priority ) ? - 1 : 1;
3112
+ }
3113
+
3114
+ /**
3115
+ * Localize date with custom format.
3116
+ *
3117
+ * @since 3.0.0
3118
+ *
3119
+ * @param string $timestamp
3120
+ * @param string $format
3121
+ * @param bool $gmt
3122
+ *
3123
+ * @return string
3124
+ */
3125
+ function learn_press_date_i18n( $timestamp = '', $format = '', $gmt = false ) {
3126
+ if ( ! $format ) {
3127
+ $format = get_option( 'date_format' );
3128
+ }
3129
+
3130
+ return date_i18n( $format, $timestamp, $gmt );
3131
}
inc/lp-template-functions.php CHANGED
@@ -151,7 +151,7 @@ if ( ! function_exists( 'learn_press_course_continue_button' ) ) {
151
$user = LP_Global::user();
152
$course = LP_Global::course();
153
154
- if (! learn_press_current_user_enrolled_course() && $course->get_external_link() ) {
155
return;
156
}
157
@@ -185,7 +185,7 @@ if ( ! function_exists( 'learn_press_course_finish_button' ) ) {
185
$user = LP_Global::user();
186
$course = LP_Global::course();
187
188
- if (! learn_press_current_user_enrolled_course() && $course->get_external_link() ) {
189
return;
190
}
191
151
$user = LP_Global::user();
152
$course = LP_Global::course();
153
154
+ if ( ! learn_press_current_user_enrolled_course() && $course->get_external_link() ) {
155
return;
156
}
157
185
$user = LP_Global::user();
186
$course = LP_Global::course();
187
188
+ if ( ! learn_press_current_user_enrolled_course() && $course->get_external_link() ) {
189
return;
190
}
191
inc/order/class-lp-order.php CHANGED
@@ -136,33 +136,35 @@ if ( ! class_exists( 'LP_Order' ) ) {
136
/**
137
* Get date of this order.
138
*
139
- * @param string $format
140
*
141
* @return string|LP_Datetime
142
*/
143
- public function get_order_date( $format = '' ) {
144
$date = $this->get_data( 'order_date' );
145
146
- $strtime = strtotime( $date->toSql() );
147
-
148
- switch ( $format ) {
149
- case 'd':
150
- $return = date_i18n( 'Y-m-d', $strtime );
151
- break;
152
- case 'h':
153
- $return = date_i18n( 'H', $strtime );
154
- break;
155
- case 'm':
156
- $return = date_i18n( 'i', $strtime );
157
- break;
158
- case 'timestamp':
159
- $return = $strtime;
160
- break;
161
- default:
162
- $return = $format ? date_i18n( $format, $strtime ) : $date;
163
}
164
165
- return $return;
166
}
167
168
/**
@@ -462,21 +464,29 @@ if ( ! class_exists( 'LP_Order' ) ) {
462
$customer = false;
463
if ( 'auto-draft' === get_post_status( $this->get_id() ) ) {
464
} else {
465
- $customer = learn_press_get_user( $this->get_data( 'user_id' ) );
466
- }
467
- if ( $customer ) {
468
- if ( ! $customer->is_exists() ) {
469
- $customer_name = $this->get_guest_customer_name();
470
- } else {
471
- if ( $customer->get_data( 'display_name' ) ) {
472
- $customer_name = $customer->get_data( 'display_name' );
473
- } elseif ( $customer->get_data( 'user_nicename' ) ) {
474
- $customer_name = $customer->get_data( 'user_nicename' );
475
- } elseif ( $customer->get_data( 'user_login' ) ) {
476
- $customer_name = $customer->get_data( 'user_login' );
477
}
478
}
479
- } else {
480
$customer_name = $this->get_guest_customer_name();
481
}
482
@@ -764,7 +774,10 @@ if ( ! class_exists( 'LP_Order' ) ) {
764
*/
765
public function get_user( $field = '' ) {
766
767
- if ( false === ( $user = learn_press_get_user( $this->get_data( 'user_id' ) ) ) ) {
768
return false;
769
}
770
@@ -785,7 +798,12 @@ if ( ! class_exists( 'LP_Order' ) ) {
785
* @return array
786
*/
787
public function get_users() {
788
- $users = (array) $this->get_data( 'user_id' );
789
790
return $users;
791
}
136
/**
137
* Get date of this order.
138
*
139
+ * @param string $context
140
*
141
* @return string|LP_Datetime
142
*/
143
+ public function get_order_date( $context = '' ) {
144
$date = $this->get_data( 'order_date' );
145
146
+ if ( 'edit' !== $context ) {
147
+ $strtime = strtotime( $date->toSql() );
148
+
149
+ switch ( $context ) {
150
+ case 'd':
151
+ $date = date_i18n( 'Y-m-d', $strtime );
152
+ break;
153
+ case 'h':
154
+ $date = date_i18n( 'H', $strtime );
155
+ break;
156
+ case 'm':
157
+ $date = date_i18n( 'i', $strtime );
158
+ break;
159
+ case 'timestamp':
160
+ $date = $strtime;
161
+ break;
162
+ default:
163
+ $date = learn_press_date_i18n( $strtime );
164
+ }
165
}
166
167
+ return $date;
168
}
169
170
/**
464
$customer = false;
465
if ( 'auto-draft' === get_post_status( $this->get_id() ) ) {
466
} else {
467
+ if ( $user_id = $this->get_data( 'user_id' ) ) {
468
+ settype( $user_id, 'array' );
469
+ $customer_name = array();
470
+ foreach ( $user_id as $uid ) {
471
+ $customer = learn_press_get_user( $uid );
472
+ if ( $customer && $customer->is_exists() ) {
473
+ if ( $customer->get_data( 'display_name' ) ) {
474
+ $customer_name[] = $customer->get_data( 'display_name' );
475
+ } elseif ( $customer->get_data( 'user_nicename' ) ) {
476
+ $customer_name[] = $customer->get_data( 'user_nicename' );
477
+ } elseif ( $customer->get_data( 'user_login' ) ) {
478
+ $customer_name[] = $customer->get_data( 'user_login' );
479
+ }
480
+ } else {
481
+ $customer_name[] = $this->get_guest_customer_name();
482
+ }
483
}
484
+
485
+ $customer_name = join( ', ', $customer_name );
486
}
487
+ }
488
+
489
+ if ( ! $customer_name ) {
490
$customer_name = $this->get_guest_customer_name();
491
}
492
774
*/
775
public function get_user( $field = '' ) {
776
777
+ $users = $this->get_users();
778
+ $uid = reset($users);
779
+
780
+ if ( false === ( $user = learn_press_get_user( $uid ) ) ) {
781
return false;
782
}
783
798
* @return array
799
*/
800
public function get_users() {
801
+ if ( $users = $this->get_data( 'user_id' ) ) {
802
+ settype( $users, 'array' );
803
+ $users = array_unique( $users );
804
+ } else {
805
+ $users = array();
806
+ }
807
808
return $users;
809
}
inc/question/class-lp-question-answers.php CHANGED
@@ -91,7 +91,7 @@ if ( ! class_exists( 'LP_Question_Answers' ) ) {
91
}
92
93
foreach ( $raw as $data ) {
94
- $key = $data['question_answer_id'];
95
$answer = new LP_Question_Answer_Option( $this->_question, $data );
96
$this->_answers[ $key ] = $answer;
97
}
91
}
92
93
foreach ( $raw as $data ) {
94
+ $key = isset( $data['question_answer_id'] ) ? $data['question_answer_id'] : 0;
95
$answer = new LP_Question_Answer_Option( $this->_question, $data );
96
$this->_answers[ $key ] = $answer;
97
}
inc/updates/learnpress-update-2.1.1.php CHANGED
@@ -2,12 +2,13 @@
2
/**
3
* Upgrade user profile picture used for avatar
4
*/
5
- $user = learn_press_get_current_user();
6
- if ( !empty( $user->get_id() ) && $user->profile_picture_type == 'picture' ) {
7
$thumb = $user->profile_picture_thumbnail_url;
8
$origin = $user->profile_picture_url;
9
$wp_upload = wp_upload_dir();
10
- $thumb = preg_replace( '!' . untrailingslashit( $wp_upload['baseurl'] ) . '/!', '', $thumb );
11
if ( file_exists( $wp_upload['basedir'] . '/' . $thumb ) ) {
12
// Update new user meta key value and remove unused meta data
13
update_user_meta( $user->get_id(), '_lp_profile_picture', $thumb );
2
/**
3
* Upgrade user profile picture used for avatar
4
*/
5
+ $user = learn_press_get_current_user();
6
+ $user_id = $user->get_id();
7
+ if ( ! empty( $user_id ) && $user->profile_picture_type == 'picture' ) {
8
$thumb = $user->profile_picture_thumbnail_url;
9
$origin = $user->profile_picture_url;
10
$wp_upload = wp_upload_dir();
11
+ $thumb = preg_replace( '!' . untrailingslashit( $wp_upload['baseurl'] ) . '/!', '', $thumb );
12
if ( file_exists( $wp_upload['basedir'] . '/' . $thumb ) ) {
13
// Update new user meta key value and remove unused meta data
14
update_user_meta( $user->get_id(), '_lp_profile_picture', $thumb );
inc/updates/learnpress-update-3.0.4.php ADDED
@@ -0,0 +1,82 @@
1
+ <?php
2
+ /**
3
+ * Todo: update emails
4
+ */
5
+
6
+
7
+ /**
8
+ * Class LP_Update_304
9
+ *
10
+ * Helper class for updating database to 3.0.4
11
+ */
12
+ class LP_Update_304 {
13
+
14
+ /**
15
+ * Entry point
16
+ */
17
+ public static function update() {
18
+ LP_Debug::startTransaction();
19
+ try {
20
+ self::update_item_meta();
21
+
22
+ LP_Install::update_db_version();
23
+ LP_Install::update_version();
24
+
25
+ set_transient( 'lp_upgraded_30', 'yes', DAY_IN_SECONDS );
26
+ LP_Debug::commitTransaction();
27
+ }
28
+ catch ( Exception $exception ) {
29
+ LP_Debug::rollbackTransaction();
30
+ }
31
+ }
32
+
33
+ public static function update_item_meta(){
34
+
35
+ }
36
+
37
+ protected static function _update_item_meta() {
38
+ global $wpdb;
39
+ $query = $wpdb->prepare( "
40
+ SELECT pm1.learnpress_user_item_id, pm1.meta_value AS question_answers, pm2.meta_value AS _question_answers
41
+ FROM {$wpdb->learnpress_user_itemmeta} pm1
42
+ LEFT JOIN {$wpdb->learnpress_user_itemmeta} pm2 ON pm1.learnpress_user_item_id = pm2.learnpress_user_item_id AND pm2.meta_key = %s
43
+ WHERE pm1.meta_key = %s
44
+ HAVING _question_answers IS NULL
45
+ LIMIT 0, 100
46
+ ", '_question_answers', 'question_answers' );
47
+
48
+ if ( ! $rows = $wpdb->get_results( $query ) ) {
49
+ return false;
50
+ }
51
+
52
+ $sqlUpdate = $wpdb->prepare( "
53
+ INSERT INTO {$wpdb->learnpress_user_itemmeta}(learnpress_user_item_id, meta_key, meta_value)
54
+ VALUES
55
+ " );
56
+
57
+ $updateRows = array();
58
+ $count = 0;
59
+ $total = sizeof( $rows );
60
+
61
+ foreach ( $rows as $k => $row ) {
62
+
63
+ if ( $row->_question_answers ) {
64
+ continue;
65
+ }
66
+
67
+ $updateRows[] = $wpdb->prepare( "(%d, %s, %s)", $row->learnpress_user_item_id, '_question_answers', $row->question_answers );
68
+ $count ++;
69
+
70
+ if ( ( $count == 10 ) || ( $k == $total - 1 ) ) {
71
+ $query = $sqlUpdate . join( ',', $updateRows );
72
+ $wpdb->query( $query );
73
+ $count = 0;
74
+ $updateRows = array();
75
+ }
76
+ }
77
+
78
+ return true;
79
+ }
80
+ }
81
+
82
+ //LP_Update_304::update();
inc/user-item/class-lp-user-item-quiz.php CHANGED
@@ -25,8 +25,11 @@ class LP_User_Item_Quiz extends LP_User_Item {
25
*
26
*/
27
protected function _parse_answers() {
28
- if ( $answers = learn_press_get_user_item_meta( $this->get_user_item_id(), '_question_answers', true ) ) {
29
- $this->_answers = $answers;
30
}
31
}
32
@@ -135,7 +138,7 @@ class LP_User_Item_Quiz extends LP_User_Item {
135
$question = LP_Question::get_question( $question_id );
136
$answered = $this->get_question_answer( $question_id );
137
138
- $check = apply_filters( 'learn-press/quiz/check-question-result', $question->check( $answered ), $question_id, $this );
139
140
$check['type'] = $question->get_type();
141
$check['answered'] = $answered !== false;
25
*
26
*/
27
protected function _parse_answers() {
28
+ foreach ( array( '_question_answers', 'question_answers' ) as $k ) {
29
+ if ( $answers = learn_press_get_user_item_meta( $this->get_user_item_id(), $k, true ) ) {
30
+ $this->_answers = $answers;
31
+ break;
32
+ }
33
}
34
}
35
138
$question = LP_Question::get_question( $question_id );
139
$answered = $this->get_question_answer( $question_id );
140
141
+ $check = apply_filters( 'learn-press/quiz/check-question-result', $question->check( $answered ), $question_id, $this );
142
143
$check['type'] = $question->get_type();
144
$check['answered'] = $answered !== false;
inc/user-item/class-lp-user-item.php CHANGED
@@ -77,7 +77,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
77
$date = new LP_Datetime( $time );
78
79
if ( $format ) {
80
- return $date->format( $format );
81
}
82
83
return $date;
@@ -90,7 +90,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
90
public function get_start_time_gmt( $format = '' ) {
91
$date = new LP_Datetime( $this->get_data( 'start_time_gmt' ) );
92
if ( $format ) {
93
- return $date->format( $format );
94
}
95
96
return $date;
@@ -115,7 +115,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
115
public function get_end_time( $format = '' ) {
116
$date = new LP_Datetime( $this->get_data( 'end_time' ) );
117
if ( $format ) {
118
- return $date->format( $format );
119
}
120
121
return $date;
@@ -140,7 +140,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
140
public function get_end_time_gmt( $format = '' ) {
141
$date = new LP_Datetime( $this->get_data( 'end_time_gmt' ) );
142
if ( $format ) {
143
- return $date->format( $format );
144
}
145
146
return $date;
@@ -414,10 +414,11 @@ class LP_User_Item extends LP_Abstract_Object_Data {
414
* @return float|int
415
*/
416
public function is_exceeded() {
417
- $time = new LP_Datetime();
418
- $current = $time->getTimestamp();
419
420
- return $this->get_exceeded_time() - $current;
421
}
422
423
/**
@@ -434,7 +435,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
434
$duration = 100 * DAY_IN_SECONDS * 360;
435
}
436
437
- return $format ? date( $format, $start_time + $duration ) : $start_time + $duration;
438
}
439
440
/**
77
$date = new LP_Datetime( $time );
78
79
if ( $format ) {
80
+ return $format = 'i18n' ? learn_press_date_i18n( $date->getTimestamp() ) : $date->format( $format );
81
}
82
83
return $date;
90
public function get_start_time_gmt( $format = '' ) {
91
$date = new LP_Datetime( $this->get_data( 'start_time_gmt' ) );
92
if ( $format ) {
93
+ return $format = 'i18n' ? learn_press_date_i18n( $date->getTimestamp() ) : $date->format( $format );
94
}
95
96
return $date;
115
public function get_end_time( $format = '' ) {
116
$date = new LP_Datetime( $this->get_data( 'end_time' ) );
117
if ( $format ) {
118
+ return $format = 'i18n' ? learn_press_date_i18n( $date->getTimestamp() ) : $date->format( $format );
119
}
120
121
return $date;
140
public function get_end_time_gmt( $format = '' ) {
141
$date = new LP_Datetime( $this->get_data( 'end_time_gmt' ) );
142
if ( $format ) {
143
+ return $format = 'i18n' ? learn_press_date_i18n( $date->getTimestamp() ) : $date->format( $format );
144
}
145
146
return $date;
414
* @return float|int
415
*/
416
public function is_exceeded() {
417
+ $time = new LP_Datetime();
418
+ $current = $time->getTimestamp();
419
+ $exceeded = $this->get_exceeded_time();
420
421
+ return false !== $exceeded ? $exceeded - $current : false;
422
}
423
424
/**
435
$duration = 100 * DAY_IN_SECONDS * 360;
436
}
437
438
+ return $duration !== false ? $format ? date( $format, $start_time + $duration ) : $start_time + $duration : false;
439
}
440
441
/**
inc/user/abstract-lp-user.php CHANGED
@@ -2547,6 +2547,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2547
public function get_course_remaining_time( $course_id ) {
2548
$course = learn_press_get_course( $course_id );
2549
$remain = false;
2550
if ( $course && $course->get_id() ) {
2551
if ( $course_data = $this->get_course_data( $course_id, true ) ) {
2552
$remain = $course_data->is_exceeded();
2547
public function get_course_remaining_time( $course_id ) {
2548
$course = learn_press_get_course( $course_id );
2549
$remain = false;
2550
+
2551
if ( $course && $course->get_id() ) {
2552
if ( $course_data = $this->get_course_data( $course_id, true ) ) {
2553
$remain = $course_data->is_exceeded();
inc/user/class-lp-profile-tabs.php CHANGED
@@ -76,7 +76,7 @@ class LP_Profile_Tabs extends LP_Array_Access {
76
77
uasort( $tabs, array( $this, '_sort_tabs' ) );
78
79
- $key = md5( serialize( $tabs ) );
80
if ( $key !== get_option( '_lp_tabs_data' ) ) {
81
flush_rewrite_rules();
82
update_option( '_lp_tabs_data', $key, false );
76
77
uasort( $tabs, array( $this, '_sort_tabs' ) );
78
79
+ $key = md5( serialize( array_keys( $tabs ) ) );
80
if ( $key !== get_option( '_lp_tabs_data' ) ) {
81
flush_rewrite_rules();
82
update_option( '_lp_tabs_data', $key, false );
inc/user/lp-user-functions.php CHANGED
@@ -129,6 +129,8 @@ if ( ! function_exists( 'learn_press_get_user' ) ) {
129
return false;
130
}
131
132
if ( $force_new || empty( LP_Global::$users[ $user_id ] ) ) {
133
LP_Global::$users[ $user_id ] = isset( $is_guest ) ? new LP_User_Guest( $user_id ) : new LP_User( $user_id );
134
}
129
return false;
130
}
131
132
+
133
+
134
if ( $force_new || empty( LP_Global::$users[ $user_id ] ) ) {
135
LP_Global::$users[ $user_id ] = isset( $is_guest ) ? new LP_User_Guest( $user_id ) : new LP_User( $user_id );
136
}
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.0.3
8
Author URI: http://thimpress.com
9
Requires at least: 3.8
10
Tested up to: 4.9.4
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.0.4
8
Author URI: http://thimpress.com
9
Requires at least: 3.8
10
Tested up to: 4.9.4
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: 4.9.4
7
- Stable tag: 3.0.3
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
@@ -198,6 +198,19 @@ https://www.transifex.com/projects/p/learnpress/
198
8. Add-ons of LearnPress.
199
200
== Changelog ==
201
= 3.0.3 =
202
~ Fixed quiz auto finish with duration is zero
203
~ Fixed pagination with quizzes in user profile
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: 4.9.4
7
+ Stable tag: 3.0.4
8
License: GPLv2 or later
9
License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
198
8. Add-ons of LearnPress.
199
200
== Changelog ==
201
+ = 3.0.4 =
202
+ ~ Improved: action when clicking to close upgrade notice
203
+ ~ Fixed: can not add course from other users to order
204
+ ~ Fixed: lost quiz data after upgrading
205
+ ~ Fixed: user can view lesson/quiz with single permalink
206
+ ~ Fixed: can not view lesson
207
+ ~ Fixed: notices in admin orders
208
+ ~ Fixed: external buy this course redirect to home page
209
+ ~ Fixed: remaining time message with course duration is zero
210
+ ~ Fixed: hidden sections action ajax admin course editor
211
+ ~ Fixed: admin can not add course to order from other users
212
+ ~ More...
213
+
214
= 3.0.3 =
215
~ Fixed quiz auto finish with duration is zero
216
~ Fixed pagination with quizzes in user profile
templates/profile/tabs.php CHANGED
@@ -26,6 +26,9 @@ $profile = LP_Profile::instance();
26
<?php
27
foreach ( $profile->get_tabs()->tabs() as $tab_key => $tab_data ) {
28
29
if ( $tab_data->is_hidden() || ! $tab_data->user_can_view() ) {
30
continue;
31
}
@@ -33,12 +36,18 @@ $profile = LP_Profile::instance();
33
$slug = $profile->get_slug( $tab_data, $tab_key );
34
$link = $profile->get_tab_link( $tab_key, true );
35
$tab_classes = array( esc_attr( $tab_key ) );
36
37
- if ( $profile->is_current_tab( $tab_key ) ) {
38
- $tab_classes[] = 'active';
39
}
40
41
- ?>
42
43
<li class="<?php echo join( ' ', $tab_classes ) ?>">
44
<!--tabs-->
@@ -47,7 +56,7 @@ $profile = LP_Profile::instance();
47
</a>
48
<!--section-->
49
50
- <?php if ( ( $sections = $tab_data->sections() ) && sizeof( $sections ) > 1 ) { ?>
51
52
<ul class="profile-tab-sections">
53
<?php foreach ( $sections as $section_key => $section_data ) {
26
<?php
27
foreach ( $profile->get_tabs()->tabs() as $tab_key => $tab_data ) {
28
29
+ /**
30
+ * @var $tab_data LP_Profile_Tab
31
+ */
32
if ( $tab_data->is_hidden() || ! $tab_data->user_can_view() ) {
33
continue;
34
}
36
$slug = $profile->get_slug( $tab_data, $tab_key );
37
$link = $profile->get_tab_link( $tab_key, true );
38
$tab_classes = array( esc_attr( $tab_key ) );
39
+ /**
40
+ * @var $tab_data LP_Profile_Tab
41
+ */
42
+ $sections = $tab_data->sections();
43
44
+ if ( $sections && sizeof( $sections ) > 1 ) {
45
+ $tab_classes[] = 'has-child';
46
}
47
48
+ if ( $profile->is_current_tab( $tab_key ) ) {
49
+ $tab_classes[] = 'active';
50
+ } ?>
51
52
<li class="<?php echo join( ' ', $tab_classes ) ?>">
53
<!--tabs-->
56
</a>
57
<!--section-->
58
59
+ <?php if ( $sections && sizeof( $sections ) > 1 ) { ?>
60
61
<ul class="profile-tab-sections">
62
<?php foreach ( $sections as $section_key => $section_data ) {
templates/profile/tabs/orders/list.php CHANGED
@@ -42,7 +42,7 @@ if ( ! $query_orders['items'] ) {
42
$order = learn_press_get_order( $order_id ); ?>
43
<tr class="order-row">
44
<td class="column-order-number"><?php echo $order->get_order_number(); ?></td>
45
- <td class="column-order-date"><?php echo $order->get_order_date( get_option( 'date_format' ) ); ?></td>
46
<td class="column-order-status">
47
<span class="lp-label label-<?php echo esc_attr( $order->get_status() ); ?>"><?php echo $order->get_order_status_html(); ?></span>
48
</td>
42
$order = learn_press_get_order( $order_id ); ?>
43
<tr class="order-row">
44
<td class="column-order-number"><?php echo $order->get_order_number(); ?></td>
45
+ <td class="column-order-date"><?php echo $order->get_order_date(); ?></td>
46
<td class="column-order-status">
47
<span class="lp-label label-<?php echo esc_attr( $order->get_status() ); ?>"><?php echo $order->get_order_status_html(); ?></span>
48
</td>
templates/profile/tabs/quizzes.php CHANGED
@@ -57,9 +57,7 @@ $query = $profile->query_quizzes( array( 'status' => $filter_status ) );
57
58
</td>
59
<td class="column-date"><?php
60
- // echo $user_quiz->get_start_time( 'd M Y' );
61
- $start_time = $user_quiz->get_start_time();
62
- echo date_i18n( get_option( 'date_format' ), $start_time->getTimestamp() ); ?></td>
63
<td class="column-status">
64
<span class="result-percent"><?php echo $user_quiz->get_percent_result(); ?></span>
65
<span class="lp-label label-<?php echo esc_attr( $user_quiz->get_results( 'status' ) ); ?>">
57
58
</td>
59
<td class="column-date"><?php
60
+ echo $user_quiz->get_start_time( 'i18n' ); ?></td>
61
<td class="column-status">
62
<span class="result-percent"><?php echo $user_quiz->get_percent_result(); ?></span>
63
<span class="lp-label label-<?php echo esc_attr( $user_quiz->get_results( 'status' ) ); ?>">
templates/single-course/buttons/external-link.php CHANGED
@@ -17,9 +17,12 @@ defined( 'ABSPATH' ) || exit();
17
$course = LP_Global::course();
18
?>
19
20
- <form name="course-external-link" class="course-external-link form-button lp-form" method="get"
21
- action="<?php echo esc_url( $course->get_external_link() ); ?>">
22
23
<button type="submit" class="lp-button button"><?php echo esc_html( $course->get_external_link_text() ); ?></button>
24
25
</form>
17
$course = LP_Global::course();
18
?>
19
20
+ <form name="course-external-link" class="course-external-link form-button lp-form" method="post">
21
22
+ <input type="hidden" name="lp-ajax" value="external-link">
23
+ <input type="hidden" name="id" value="<?php echo $course->get_id(); ?>">
24
+ <input type="hidden" name="nonce"
25
+ value="<?php echo wp_create_nonce( 'external-link-' . $course->get_external_link() ); ?>">
26
<button type="submit" class="lp-button button"><?php echo esc_html( $course->get_external_link_text() ); ?></button>
27
28
</form>
templates/single-course/remaining-time.php CHANGED
@@ -4,19 +4,19 @@
4
*
5
* @author ThimPress
6
* @package LearnPress/Templates
7
- * @version 3.0.0
8
*/
9
10
defined( 'ABSPATH' ) or die();
11
12
- if ( ! isset( $remaining_time ) ) {
13
- return;
14
- }
15
-
16
?>
17
<div class="course-remaining-time">
18
<p>
19
<?php learn_press_label_html( __( 'Enrolled', 'learnpress' ), 'enrolled' ); ?>
20
- <?php echo sprintf( __( 'You have %s remaining for the course', 'learnpress' ), $remaining_time ); ?>
21
</p>
22
</div>
4
*
5
* @author ThimPress
6
* @package LearnPress/Templates
7
+ * @version 3.0.4
8
*/
9
10
defined( 'ABSPATH' ) or die();
11
12
+ $course = LP_Global::course();
13
?>
14
<div class="course-remaining-time">
15
<p>
16
<?php learn_press_label_html( __( 'Enrolled', 'learnpress' ), 'enrolled' ); ?>
17
+ <?php
18
+ if ( isset( $remaining_time ) && $course->get_duration() ) {
19
+ echo sprintf( __( 'You have %s remaining for the course', 'learnpress' ), $remaining_time );
20
+ } ?>
21
</p>
22
</div>
templates/single-course/section/content-item.php CHANGED
@@ -1,10 +1,18 @@
1
<?php
2
/**
3
- * Created by PhpStorm.
4
- * User: tu
5
- * Date: 12/14/17
6
- * Time: 2:56 PM
7
*/
8
9
$args = array( 'item' => $item, 'section' => $section );
10
1
<?php
2
/**
3
+ * Template for displaying content item in single course.
4
+ *
5
+ * This template can be overridden by copying it to yourtheme/learnpress/single-course/section/content-item.php.
6
+ *
7
+ * @author ThimPress
8
+ * @package Learnpress/Templates
9
+ * @version 3.0.0
10
+ */
11
+
12
+ /**
13
+ * Prevent loading this file directly
14
*/
15
+ defined( 'ABSPATH' ) || exit();
16
17
$args = array( 'item' => $item, 'section' => $section );
18