LearnPress – WordPress LMS Plugin - Version 3.0.6

Version Description

~ Fixed: missing 'Instructors Registration' option ~ Fixed: cannot start quiz or complete lesson ~ Fixed: can view a quiz/lesson although it does not assign to a course ~ Fixed: wrong count number in courses manage ~ Fixed: cannot save some settings options ~ Fixed: missing hook ~ Fixed: user can view lesson with single post type link ~ Fixed: issue with 'Buy This Course' button ~ Fixed: cannot change course author ~ Fixed: issue with Become a Teacher form ~ Fixed: instructor cannot add iframe into course/lesson/quiz content ~ Improved: auto detect video in lesson content and move it to the top (move to option) ~ Improved something...

Download this release

Release Info

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

Code changes from version 3.0.5 to 3.0.6

Files changed (136) hide show
  1. assets/css/learnpress.css +17 -9
  2. assets/images/closedhand.cur +0 -0
  3. assets/js/admin/admin.js +26 -1
  4. assets/js/admin/course-editor.js +1 -2
  5. assets/js/admin/update.js +10 -1
  6. assets/js/frontend/course.js +7 -4
  7. assets/scss/frontend/_curriculum.scss +13 -11
  8. assets/scss/frontend/_profile.scss +16 -8
  9. assets/scss/learnpress.scss +10 -1
  10. inc/abstracts/abstract-post-data.php +5 -0
  11. inc/admin/class-lp-admin-ajax.php +19 -11
  12. inc/admin/editor/class-lp-admin-editor-course.php +5 -10
  13. inc/admin/lp-admin-functions.php +15 -17
  14. inc/admin/meta-box/class-lp-meta-box-helper.php +5 -2
  15. inc/admin/settings/abstract-settings-page.php +2 -3
  16. inc/admin/settings/class-lp-settings-advanced.php +11 -0
  17. inc/admin/settings/class-lp-settings-emails.php +2 -0
  18. inc/admin/settings/class-lp-settings-general.php +0 -8
  19. inc/admin/settings/class-lp-settings-pages.php +7 -0
  20. inc/admin/sub-menus/class-lp-submenu-settings.php +4 -1
  21. inc/admin/views/course/section.php +1 -1
  22. inc/admin/views/setup/notice-setup.php +1 -1
  23. inc/class-lp-ajax.php +1 -1
  24. inc/class-lp-page-controller.php +21 -10
  25. inc/class-lp-preview-course.php +0 -4
  26. inc/course/abstract-course.php +2 -2
  27. inc/curds/class-lp-question-curd.php +1 -1
  28. inc/curds/class-lp-section-curd.php +56 -20
  29. inc/custom-post-types/course.php +7 -6
  30. inc/custom-post-types/lesson.php +1 -8
  31. inc/custom-post-types/question.php +0 -6
  32. inc/custom-post-types/quiz.php +1 -8
  33. inc/debug.php +15 -4
  34. inc/emails/class-lp-email-become-an-instructor.php +1 -1
  35. inc/emails/class-lp-email-cancelled-order-admin.php +1 -1
  36. inc/emails/class-lp-email-completed-order-user.php +2 -0
  37. inc/emails/class-lp-email-enrolled-course-admin.php +4 -4
  38. inc/emails/class-lp-email-finished-course-admin.php +1 -1
  39. inc/emails/class-lp-email-new-course.php +1 -1
  40. inc/emails/class-lp-email-new-order-admin.php +1 -1
  41. inc/emails/class-lp-email.php +18 -0
  42. inc/libraries/meta-box/css/background.css +17 -0
  43. inc/libraries/meta-box/css/button-group.css +68 -0
  44. inc/libraries/meta-box/css/fieldset-text.css +4 -0
  45. inc/libraries/meta-box/css/file-input.css +6 -0
  46. inc/libraries/meta-box/css/switch.css +94 -0
  47. inc/libraries/meta-box/inc/about/about.php +125 -0
  48. inc/libraries/meta-box/inc/about/css/style.css +57 -0
  49. inc/libraries/meta-box/inc/about/images/meta-box.png +0 -0
  50. inc/libraries/meta-box/inc/about/images/online-generator.png +0 -0
  51. inc/libraries/meta-box/inc/about/js/script.js +22 -0
  52. inc/libraries/meta-box/inc/about/sections/getting-started.php +41 -0
  53. inc/libraries/meta-box/inc/about/sections/tabs.php +12 -0
  54. inc/libraries/meta-box/inc/about/sections/welcome.php +17 -0
  55. inc/libraries/meta-box/inc/storages/base.php +98 -0
  56. inc/libraries/meta-box/js/button-group.js +37 -0
  57. inc/libraries/meta-box/js/script.js +4 -0
  58. inc/libraries/meta-box/js/wp-color-picker-alpha/wp-color-picker-alpha.min.js +13 -0
  59. inc/libraries/meta-box/languages/default.pot +0 -179
  60. inc/libraries/meta-box/languages/meta-box-ar.mo +0 -0
  61. inc/libraries/meta-box/languages/meta-box-ar.po +0 -122
  62. inc/libraries/meta-box/languages/meta-box-de_DE.mo +0 -0
  63. inc/libraries/meta-box/languages/meta-box-de_DE.po +0 -160
  64. inc/libraries/meta-box/languages/meta-box-fa_IR.mo +0 -0
  65. inc/libraries/meta-box/languages/meta-box-fa_IR.po +0 -184
  66. inc/libraries/meta-box/languages/meta-box-fr_FR.mo +0 -0
  67. inc/libraries/meta-box/languages/meta-box-fr_FR.po +0 -456
  68. inc/libraries/meta-box/languages/meta-box-it_IT.mo +0 -0
  69. inc/libraries/meta-box/languages/meta-box-it_IT.po +0 -126
  70. inc/libraries/meta-box/languages/meta-box-nb_NO.mo +0 -0
  71. inc/libraries/meta-box/languages/meta-box-nb_NO.po +0 -149
  72. inc/libraries/meta-box/languages/meta-box-nl_NL.mo +0 -0
  73. inc/libraries/meta-box/languages/meta-box-nl_NL.po +0 -130
  74. inc/libraries/meta-box/languages/meta-box-pl_PL.mo +0 -0
  75. inc/libraries/meta-box/languages/meta-box-pl_PL.po +0 -215
  76. inc/libraries/meta-box/languages/meta-box-pt_BR.mo +0 -0
  77. inc/libraries/meta-box/languages/meta-box-pt_BR.po +0 -124
  78. inc/libraries/meta-box/languages/meta-box-ru_RU.mo +0 -0
  79. inc/libraries/meta-box/languages/meta-box-ru_RU.po +0 -637
  80. inc/libraries/meta-box/languages/meta-box-sv_SE.mo +0 -0
  81. inc/libraries/meta-box/languages/meta-box-sv_SE.po +0 -118
  82. inc/libraries/meta-box/languages/meta-box-tr_TR.mo +0 -0
  83. inc/libraries/meta-box/languages/meta-box-tr_TR.po +0 -180
  84. inc/libraries/meta-box/languages/meta-box-zh_CN.mo +0 -0
  85. inc/libraries/meta-box/languages/meta-box-zh_CN.po +0 -189
  86. inc/libraries/meta-box/languages/meta-box-zh_TW.mo +0 -0
  87. inc/libraries/meta-box/languages/meta-box-zh_TW.po +0 -189
  88. inc/libraries/meta-box/languages/readme.md +0 -19
  89. inc/libraries/wp-background-process.php +20 -19
  90. inc/lp-constants.php +2 -2
  91. inc/lp-core-functions.php +22 -18
  92. inc/lp-template-functions.php +58 -6
  93. inc/lp-template-hooks.php +2 -0
  94. inc/order/class-lp-order.php +0 -1
  95. inc/shortcodes/class-lp-shortcode-become-a-teacher.php +1 -2
  96. inc/user-item/class-lp-user-item-course.php +25 -17
  97. inc/user-item/class-lp-user-item-quiz.php +4 -6
  98. inc/user/abstract-lp-user.php +10 -19
  99. inc/user/class-lp-profile-tabs.php +25 -8
  100. inc/user/class-lp-profile.php +49 -22
  101. inc/user/lp-user-functions.php +1 -1
  102. languages/learnpress.pot +1001 -883
  103. learnpress.php +1 -4
  104. readme.txt +16 -406
  105. templates/content-lesson/video/content.php +1 -1
  106. templates/emails/plain/become-an-instructor.php +0 -1
  107. templates/emails/plain/cancelled-order-admin.php +0 -1
  108. templates/emails/plain/cancelled-order-guest.php +0 -1
  109. templates/emails/plain/cancelled-order-instructor.php +0 -1
  110. templates/emails/plain/cancelled-order-user.php +0 -1
  111. templates/emails/plain/completed-order-guest.php +0 -1
  112. templates/emails/plain/completed-order-user.php +0 -1
  113. templates/emails/plain/enrolled-course-admin.php +0 -1
  114. templates/emails/plain/enrolled-course-instructor.php +0 -1
  115. templates/emails/plain/enrolled-course-user.php +0 -1
  116. templates/emails/plain/enrolled-course.php +0 -1
  117. templates/emails/plain/finished-course-admin.php +0 -1
  118. templates/emails/plain/finished-course-instructor.php +0 -1
  119. templates/emails/plain/finished-course-user.php +0 -1
  120. templates/emails/plain/finished-course.php +0 -1
  121. templates/emails/plain/instructor-accepted.php +0 -1
  122. templates/emails/plain/new-course.php +0 -1
  123. templates/emails/plain/new-order-admin.php +0 -1
  124. templates/emails/plain/new-order-guest.php +0 -1
  125. templates/emails/plain/new-order-instructor.php +0 -1
  126. templates/emails/plain/new-order-user.php +0 -1
  127. templates/emails/plain/processing-order-guest.php +0 -1
  128. templates/emails/plain/processing-order-user.php +0 -1
  129. templates/emails/plain/published-course.php +0 -1
  130. templates/emails/plain/rejected-course.php +0 -1
  131. templates/emails/plain/update-course.php +0 -1
  132. templates/emails/plain/user-order-changed-status.php +0 -1
  133. templates/emails/plain/user-order-completed.php +0 -1
  134. templates/single-course/buttons.php +0 -2
  135. templates/single-course/content-item-lp_lesson.php +2 -1
  136. templates/single-course/progress.php +1 -1
assets/css/learnpress.css CHANGED
@@ -221,13 +221,6 @@
221
222
#learn-press-user-profile {
223
position: relative; }
224
- #learn-press-user-profile:before {
225
- position: absolute;
226
- content: '';
227
- width: 200px;
228
- top: 0;
229
- bottom: 0;
230
- background: #f5f5f5; }
231
#learn-press-user-profile:after {
232
clear: both;
233
display: block;
@@ -252,6 +245,13 @@
252
background: #f5f5f5;
253
/*margin-bottom: -20000px;
254
padding-bottom: 20000px;*/ }
255
#learn-press-profile-nav .tabs {
256
list-style: none;
257
margin: 0;
@@ -942,14 +942,14 @@ body.course-item-popup {
942
margin-bottom: 50px; }
943
body.course-item-popup .content-item-summary > h3 {
944
margin-bottom: 20px; }
945
- body.course-item-popup .content-item-summary .entry-video {
946
position: absolute;
947
top: 0;
948
left: 0;
949
width: 100%;
950
background: #000;
951
line-height: 1; }
952
- body.course-item-popup .content-item-summary .entry-video iframe {
953
width: 100%;
954
margin-bottom: 0;
955
max-width: 900px;
@@ -2014,6 +2014,14 @@ ul.list-table-nav {
2014
.course-item-nav .next {
2015
text-align: right; }
2016
2017
@media screen and (max-width: 768px) {
2018
ul.learn-press-courses .course {
2019
width: 48%; } }
221
222
#learn-press-user-profile {
223
position: relative; }
224
#learn-press-user-profile:after {
225
clear: both;
226
display: block;
245
background: #f5f5f5;
246
/*margin-bottom: -20000px;
247
padding-bottom: 20000px;*/ }
248
+ #learn-press-profile-nav:before {
249
+ content: '';
250
+ width: 200px;
251
+ background: #F5F5F5;
252
+ top: 0;
253
+ bottom: 0;
254
+ position: absolute; }
255
#learn-press-profile-nav .tabs {
256
list-style: none;
257
margin: 0;
942
margin-bottom: 50px; }
943
body.course-item-popup .content-item-summary > h3 {
944
margin-bottom: 20px; }
945
+ body.course-item-popup .content-item-summary.content-item-video .entry-video {
946
position: absolute;
947
top: 0;
948
left: 0;
949
width: 100%;
950
background: #000;
951
line-height: 1; }
952
+ body.course-item-popup .content-item-summary.content-item-video .entry-video iframe {
953
width: 100%;
954
margin-bottom: 0;
955
max-width: 900px;
2014
.course-item-nav .next {
2015
text-align: right; }
2016
2017
+ .content-item-wrap #comments {
2018
+ margin-left: 0;
2019
+ margin-right: 0; }
2020
+ .content-item-wrap #comments #comment {
2021
+ -webkit-box-sizing: border-box;
2022
+ -moz-box-sizing: border-box;
2023
+ box-sizing: border-box; }
2024
+
2025
@media screen and (max-width: 768px) {
2026
ul.learn-press-courses .course {
2027
width: 48%; } }
assets/images/closedhand.cur ADDED
Binary file
assets/js/admin/admin.js CHANGED
@@ -354,6 +354,30 @@
354
});
355
}
356
357
var $doc = $(document);
358
359
function _ready() {
@@ -376,7 +400,8 @@
376
.on('click', '#_lp_sale_price_schedule_cancel', toggleSalePriceSchedule)
377
.on('click', '.lp-upgrade-notice .close-notice', hideUpgradeMessage)
378
.on('click', '.plugin-action-buttons a', pluginActions)
379
- .on('click', '.learn-press-filter-template', _callbackFilterTemplates);
380
381
LP_Admin.init();
382
}
354
});
355
}
356
357
+ function _duplicatePost(e) {
358
+ e.preventDefault();
359
+
360
+ var _self = $(this),
361
+ _id = _self.data('post-id');
362
+
363
+ $.ajax({
364
+ url: '',
365
+ data: {
366
+ 'lp-ajax': 'duplicator',
367
+ id: _id
368
+ },
369
+ success: function (response) {
370
+ response = LP.parseJSON(response);
371
+
372
+ if (response.success) {
373
+ window.location.href = response.data;
374
+ } else {
375
+ alert(response.data);
376
+ }
377
+ }
378
+ });
379
+ }
380
+
381
var $doc = $(document);
382
383
function _ready() {
400
.on('click', '#_lp_sale_price_schedule_cancel', toggleSalePriceSchedule)
401
.on('click', '.lp-upgrade-notice .close-notice', hideUpgradeMessage)
402
.on('click', '.plugin-action-buttons a', pluginActions)
403
+ .on('click', '.learn-press-filter-template', _callbackFilterTemplates)
404
+ .on('click', '.lp-duplicate-row-action .lp-duplicate-post', _duplicatePost);
405
406
LP_Admin.init();
407
}
assets/js/admin/course-editor.js CHANGED
@@ -368,8 +368,7 @@ var LP_Curriculum_Sections_Store = (function (Vue, helpers, data) {
368
Vue.http.LPRequest({
369
type: 'update-section-items',
370
section_id: payload.section_id,
371
- items: JSON.stringify(payload.items),
372
- last_section: state.sections[state.sections.length - 1] === (payload.section_id)
373
}).then(
374
function (response) {
375
var result = response.body;
368
Vue.http.LPRequest({
369
type: 'update-section-items',
370
section_id: payload.section_id,
371
+ items: JSON.stringify(payload.items)
372
}).then(
373
function (response) {
374
var result = response.body;
assets/js/admin/update.js CHANGED
@@ -41,7 +41,16 @@
41
}
42
}
43
});
44
- })
45
}
46
47
$(document).ready(init);
41
}
42
}
43
});
44
+ }).on('click', '#skip-notice-install', function(){
45
+ $.post({
46
+ url: '',
47
+ data: {
48
+ 'lp-ajax': 'skip-notice-install'
49
+ }
50
+ });
51
+
52
+ $('#notice-install').fadeOut();
53
+ });
54
}
55
56
$(document).ready(init);
assets/js/frontend/course.js CHANGED
@@ -380,8 +380,13 @@
380
}
381
382
function fitVideo() {
383
- var $wrapContent = $('.content-item-summary'),
384
- $entryVideo = $wrapContent.find('.entry-video'),
385
$frame = $entryVideo.find('iframe'),
386
width = $frame.attr('width'),
387
height = $frame.attr('height'),
@@ -405,8 +410,6 @@
405
return false;
406
}
407
408
- $wrapContent.addClass('content-item-video');
409
-
410
if (width && height) {
411
if (width.indexOf('%') === -1 && height.indexOf('%') === -1) {
412
ratio = height / width;
380
}
381
382
function fitVideo() {
383
+ var $wrapContent = $('.content-item-summary.content-item-video');
384
+
385
+ if (!$wrapContent.length) {
386
+ return;
387
+ }
388
+
389
+ var $entryVideo = $wrapContent.find('.entry-video'),
390
$frame = $entryVideo.find('iframe'),
391
width = $frame.attr('width'),
392
height = $frame.attr('height'),
410
return false;
411
}
412
413
if (width && height) {
414
if (width.indexOf('%') === -1 && height.indexOf('%') === -1) {
415
ratio = height / width;
assets/scss/frontend/_curriculum.scss CHANGED
@@ -503,18 +503,20 @@ body {
503
& > h3 {
504
margin-bottom: 20px;
505
}
506
- .entry-video {
507
- position: absolute;
508
- top: 0;
509
- left: 0;
510
- width: 100%;
511
- background: #000;
512
- line-height: 1;
513
- iframe {
514
width: 100%;
515
- margin-bottom: 0;
516
- max-width: 900px;
517
- vertical-align: top;
518
}
519
}
520
}
503
& > h3 {
504
margin-bottom: 20px;
505
}
506
+ &.content-item-video {
507
+ .entry-video {
508
+ position: absolute;
509
+ top: 0;
510
+ left: 0;
511
width: 100%;
512
+ background: #000;
513
+ line-height: 1;
514
+ iframe {
515
+ width: 100%;
516
+ margin-bottom: 0;
517
+ max-width: 900px;
518
+ vertical-align: top;
519
+ }
520
}
521
}
522
}
assets/scss/frontend/_profile.scss CHANGED
@@ -1,13 +1,13 @@
1
#learn-press-user-profile {
2
position: relative;
3
- &:before {
4
- position: absolute;
5
- content: '';
6
- width: 200px;
7
- top: 0;
8
- bottom: 0;
9
- background: #f5f5f5;
10
- }
11
12
&:after {
13
@include clear-fix();
@@ -36,6 +36,14 @@
36
background: #f5f5f5;
37
/*margin-bottom: -20000px;
38
padding-bottom: 20000px;*/
39
.tabs {
40
list-style: none;
41
margin: 0;
1
#learn-press-user-profile {
2
position: relative;
3
+ //&:before {
4
+ // position: absolute;
5
+ // content: '';
6
+ // width: 200px;
7
+ // top: 0;
8
+ // bottom: 0;
9
+ // background: #f5f5f5;
10
+ //}
11
12
&:after {
13
@include clear-fix();
36
background: #f5f5f5;
37
/*margin-bottom: -20000px;
38
padding-bottom: 20000px;*/
39
+ &:before{
40
+ content: '';
41
+ width: 200px;
42
+ background: #F5F5F5;
43
+ top: 0;
44
+ bottom: 0;
45
+ position: absolute;
46
+ }
47
.tabs {
48
list-style: none;
49
margin: 0;
assets/scss/learnpress.scss CHANGED
@@ -353,13 +353,22 @@ ul.list-table-nav {
353
text-align: right;
354
}
355
}
356
-
357
@media screen and (max-width: 768px) {
358
ul.learn-press-courses {
359
.course {
360
width: 48%;
361
}
362
}
363
}
364
365
@media screen and (max-width: 600px) {
353
text-align: right;
354
}
355
}
356
+ .content-item-wrap {
357
+ #comments {
358
+ margin-left: 0;
359
+ margin-right: 0;
360
+ #comment{
361
+ @include box-sizing(border-box);
362
+ }
363
+ }
364
+ }
365
@media screen and (max-width: 768px) {
366
ul.learn-press-courses {
367
.course {
368
width: 48%;
369
}
370
}
371
+
372
}
373
374
@media screen and (max-width: 600px) {
inc/abstracts/abstract-post-data.php CHANGED
@@ -164,6 +164,11 @@ if ( ! class_exists( 'LP_Abstract_Post_Data' ) ) {
164
}
165
166
public function get_video() {
167
if ( ( $content = $this->get_content() ) && ( $this->_video === null ) ) {
168
$video = get_media_embedded_in_content( $content, array( 'video', 'object', 'embed', 'iframe' ) );
169
164
}
165
166
public function get_video() {
167
+
168
+ if ( 'yes' !== LP()->settings->get( 'enable_lesson_video' ) ) {
169
+ return false;
170
+ }
171
+
172
if ( ( $content = $this->get_content() ) && ( $this->_video === null ) ) {
173
$video = get_media_embedded_in_content( $content, array( 'video', 'object', 'embed', 'iframe' ) );
174
inc/admin/class-lp-admin-ajax.php CHANGED
@@ -85,7 +85,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
85
'add_items_to_order',
86
'remove_items_from_order',
87
'update_email_status',
88
- 'create-pages'
89
);
90
foreach ( $ajax_events as $action => $callback ) {
91
@@ -105,6 +106,13 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
105
}
106
}
107
108
/**
109
* Handle ajax admin course editor.
110
*
@@ -158,13 +166,13 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
158
* @since 3.0.0
159
*/
160
public static function duplicator() {
161
- $args = wp_parse_args( $_REQUEST, array( 'id' => false ) );
162
163
// get post type
164
- $post_type = get_post_type( $args['id'] );
165
166
- if ( ! $args['id'] ) {
167
- LP_Admin_Notice::add_redirect( new WP_Error( __( '<p>Ops! ID not found</p>', 'learnpress' ) ), 'error' );
168
} else {
169
170
$new_item_id = '';
@@ -174,28 +182,28 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
174
switch ( $post_type ) {
175
case LP_COURSE_CPT:
176
$curd = new LP_Course_CURD();
177
- $new_item_id = $curd->duplicate( $args['id'], $duplicate_args );
178
break;
179
case LP_LESSON_CPT:
180
$curd = new LP_Lesson_CURD();
181
- $new_item_id = $curd->duplicate( $args['id'], $duplicate_args );
182
break;
183
case LP_QUIZ_CPT:
184
$curd = new LP_Quiz_CURD();
185
- $new_item_id = $curd->duplicate( $args['id'], $duplicate_args );
186
break;
187
case LP_QUESTION_CPT:
188
$curd = new LP_Question_CURD();
189
- $new_item_id = $curd->duplicate( $args['id'], $duplicate_args );
190
break;
191
default:
192
break;
193
}
194
195
if ( is_wp_error( $new_item_id ) ) {
196
- LP_Admin_Notice::add_redirect( $new_item_id->get_error_message(), 'error' );
197
} else {
198
- wp_redirect( admin_url( 'post.php?post=' . $new_item_id . '&action=edit' ) );
199
}
200
201
}
85
'add_items_to_order',
86
'remove_items_from_order',
87
'update_email_status',
88
+ 'create-pages',
89
+ 'skip-notice-install'
90
);
91
foreach ( $ajax_events as $action => $callback ) {
92
106
}
107
}
108
109
+ /**
110
+ * Hide notice install
111
+ */
112
+ public static function skip_notice_install() {
113
+ delete_option( 'learn_press_install' );
114
+ }
115
+
116
/**
117
* Handle ajax admin course editor.
118
*
166
* @since 3.0.0
167
*/
168
public static function duplicator() {
169
+ $post_id = LP_Request::get_string( 'id' );
170
171
// get post type
172
+ $post_type = get_post_type( $post_id );
173
174
+ if ( ! $post_id ) {
175
+ learn_press_send_json_error( __( 'Ops! ID not found', 'learnpress' ) );
176
} else {
177
178
$new_item_id = '';
182
switch ( $post_type ) {
183
case LP_COURSE_CPT:
184
$curd = new LP_Course_CURD();
185
+ $new_item_id = $curd->duplicate( $post_id, $duplicate_args );
186
break;
187
case LP_LESSON_CPT:
188
$curd = new LP_Lesson_CURD();
189
+ $new_item_id = $curd->duplicate( $post_id, $duplicate_args );
190
break;
191
case LP_QUIZ_CPT:
192
$curd = new LP_Quiz_CURD();
193
+ $new_item_id = $curd->duplicate( $post_id, $duplicate_args );
194
break;
195
case LP_QUESTION_CPT:
196
$curd = new LP_Question_CURD();
197
+ $new_item_id = $curd->duplicate( $post_id, $duplicate_args );
198
break;
199
default:
200
break;
201
}
202
203
if ( is_wp_error( $new_item_id ) ) {
204
+ learn_press_send_json_error( __( 'Duplicate post fail, please try again', 'learnpress' ) );
205
} else {
206
+ learn_press_send_json_success( admin_url( 'post.php?post=' . $new_item_id . '&action=edit' ) );
207
}
208
209
}
inc/admin/editor/class-lp-admin-editor-course.php CHANGED
@@ -108,10 +108,8 @@ class LP_Admin_Editor_Course extends LP_Admin_Editor {
108
109
$this->result = $this->section_curd->sort_sections( $order );
110
111
- // last section
112
- $last_section_id = end( $order );
113
// update final quiz
114
- $this->section_curd->update_final_quiz( $last_section_id );
115
}
116
117
/**
@@ -270,10 +268,9 @@ class LP_Admin_Editor_Course extends LP_Admin_Editor {
270
* @return mixed
271
*/
272
public function update_section_items( $args = array() ) {
273
- $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
274
- $last_section = ! empty( $args['last_section'] ) ? $args['last_section'] : false;
275
- $items = ! empty( $args['items'] ) ? $args['items'] : false;
276
- $items = json_decode( wp_unslash( $items ), true );
277
278
if ( ! ( $section_id && $items ) ) {
279
return false;
@@ -281,9 +278,7 @@ class LP_Admin_Editor_Course extends LP_Admin_Editor {
281
282
$this->result = $this->section_curd->update_section_items( $section_id, $items );
283
284
- if ( $last_section ) {
285
- $this->section_curd->update_final_quiz( $section_id );
286
- }
287
288
return true;
289
}
108
109
$this->result = $this->section_curd->sort_sections( $order );
110
111
// update final quiz
112
+ $this->section_curd->update_final_item();
113
}
114
115
/**
268
* @return mixed
269
*/
270
public function update_section_items( $args = array() ) {
271
+ $section_id = ! empty( $args['section_id'] ) ? $args['section_id'] : false;
272
+ $items = ! empty( $args['items'] ) ? $args['items'] : false;
273
+ $items = json_decode( wp_unslash( $items ), true );
274
275
if ( ! ( $section_id && $items ) ) {
276
return false;
278
279
$this->result = $this->section_curd->update_section_items( $section_id, $items );
280
281
+ $this->section_curd->update_final_item();
282
283
return true;
284
}
inc/admin/lp-admin-functions.php CHANGED
@@ -25,41 +25,39 @@ if ( ! function_exists( 'learn_press_add_row_action_link' ) ) {
25
global $post;
26
27
if ( LP_COURSE_CPT == $post->post_type ) {
28
- $duplicate_link = admin_url( 'edit.php?post_type=' . LP_COURSE_CPT . '&lp-ajax=duplicator&id=' . $post->ID );
29
$duplicate_link = array(
30
array(
31
'link' => $duplicate_link,
32
'title' => __( 'Duplicate this course', 'learnpress' ),
33
- 'class' => 'lp-duplicate-course'
34
)
35
);
36
$links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
37
if ( count( $links ) > 1 ) {
38
$drop_down = array( '<ul class="lpr-row-action-dropdown">' );
39
foreach ( $links as $link ) {
40
- $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] ) . '</li>';
41
};
42
$drop_down[] = '</ul>';
43
$link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
44
} else {
45
$link = array_shift( $links );
46
- $link = sprintf( '<a href="%s" class="%s">%s</a>', $link['link'], $link['class'], $link['title'] );
47
}
48
$actions['lp-duplicate-row-action'] = $link;
49
} else if ( LP_QUIZ_CPT === $post->post_type ) {
50
unset( $actions['view'] );
51
- $url = admin_url( 'edit.php?post_type=' . LP_QUIZ_CPT . '&lp-ajax=duplicator&id=' . $post->ID );
52
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this quiz', 'learnpress' ) );
53
$actions['lp-duplicate-row-action'] = $link;
54
} else if ( LP_QUESTION_CPT === $post->post_type ) {
55
unset( $actions['view'] );
56
- $url = admin_url( 'edit.php?post_type=' . LP_QUESTION_CPT . '&lp-ajax=duplicator&id=' . $post->ID );
57
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this question', 'learnpress' ) );
58
$actions['lp-duplicate-row-action'] = $link;
59
} else if ( LP_LESSON_CPT === $post->post_type ) {
60
unset( $actions['view'] );
61
- $url = admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&lp-ajax=duplicator&id=' . $post->ID );
62
- $link = sprintf( '<a href="%s" class="lp-duplicate-lesson">%s</a>', $url, __( 'Duplicate this lesson', 'learnpress' ) );
63
$actions['lp-duplicate-row-action'] = $link;
64
}
65
@@ -137,7 +135,7 @@ 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
*
@@ -173,7 +171,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
*/
@@ -1676,9 +1674,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
*/
@@ -2188,7 +2186,7 @@ function learn_press_touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $mult
2188
* @since 3.0.4
2189
*
2190
* @param int|string $context_id
2191
- * @param string $context
2192
*
2193
* @return bool|int|string
2194
*/
@@ -2207,7 +2205,7 @@ add_filter( 'learn-press/modal-search-items/context-id', 'learn_press_modal_sear
2207
*
2208
* @since 3.0.0
2209
*
2210
- * @param string $link
2211
* @param WP_Post $post
2212
*
2213
* @return string
@@ -2216,7 +2214,7 @@ function learn_press_preview_post_link( $link, $post ) {
2216
$items = learn_press_course_get_support_item_types( true );
2217
2218
if ( in_array( $post->post_type, $items ) ) {
2219
- $link = learn_press_course_item_type_link($link, $post);
2220
}
2221
2222
return $link;
25
global $post;
26
27
if ( LP_COURSE_CPT == $post->post_type ) {
28
+ $duplicate_link = '#';
29
$duplicate_link = array(
30
array(
31
'link' => $duplicate_link,
32
'title' => __( 'Duplicate this course', 'learnpress' ),
33
+ 'class' => 'lp-duplicate-post lp-duplicate-course',
34
+ 'data' => $post->ID
35
)
36
);
37
$links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
38
if ( count( $links ) > 1 ) {
39
$drop_down = array( '<ul class="lpr-row-action-dropdown">' );
40
foreach ( $links as $link ) {
41
+ $drop_down[] = '<li>' . sprintf( '<a href="%s" class="%s" data-post-id="%s">%s</a>', $link['link'], $link['class'], $link['data'], $link['title'] ) . '</li>';
42
};
43
$drop_down[] = '</ul>';
44
$link = sprintf( '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>', 'javascript: void(0);', __( 'Course', 'learnpress' ), join( "\n", $drop_down ) );
45
} else {
46
$link = array_shift( $links );
47
+ $link = sprintf( '<a href="%s" class="%s" data-post-id="%s">%s</a>', $link['link'], $link['class'], $link['data'], $link['title'] );
48
}
49
$actions['lp-duplicate-row-action'] = $link;
50
} else if ( LP_QUIZ_CPT === $post->post_type ) {
51
unset( $actions['view'] );
52
+ $link = sprintf( '<a href="#" class="lp-duplicate-post lp-duplicate-quiz" data-post-id="%s">%s</a>', $post->ID, __( 'Duplicate this quiz', 'learnpress' ) );
53
$actions['lp-duplicate-row-action'] = $link;
54
} else if ( LP_QUESTION_CPT === $post->post_type ) {
55
unset( $actions['view'] );
56
+ $link = sprintf( '<a href="#" class="lp-duplicate-post lp-duplicate-question" data-post-id="%s">%s</a>', $post->ID, __( 'Duplicate this question', 'learnpress' ) );
57
$actions['lp-duplicate-row-action'] = $link;
58
} else if ( LP_LESSON_CPT === $post->post_type ) {
59
unset( $actions['view'] );
60
+ $link = sprintf( '<a href="#" class="lp-duplicate-post lp-duplicate-lesson" data-post-id="%s">%s</a>', $post->ID, __( 'Duplicate this lesson', 'learnpress' ) );
61
$actions['lp-duplicate-row-action'] = $link;
62
}
63
135
* Find a full path of a view and display the content in admin
136
*
137
* @param $name
138
+ * @param array $args
139
* @param bool|false $include_once
140
* @param bool
141
*
171
*
172
* @param $name
173
* @param bool|false $selected
174
+ * @param array $args
175
*
176
* @return mixed|string
177
*/
1674
*
1675
* @since 3.0.0
1676
*
1677
+ * @param null $post_id
1678
* @param array $args
1679
+ * @param bool $meta
1680
*
1681
* @return bool|mixed
1682
*/
2186
* @since 3.0.4
2187
*
2188
* @param int|string $context_id
2189
+ * @param string $context
2190
*
2191
* @return bool|int|string
2192
*/
2205
*
2206
* @since 3.0.0
2207
*
2208
+ * @param string $link
2209
* @param WP_Post $post
2210
*
2211
* @return string
2214
$items = learn_press_course_get_support_item_types( true );
2215
2216
if ( in_array( $post->post_type, $items ) ) {
2217
+ $link = learn_press_course_item_type_link( $link, $post );
2218
}
2219
2220
return $link;
inc/admin/meta-box/class-lp-meta-box-helper.php CHANGED
@@ -59,8 +59,11 @@ if ( ! class_exists( 'LP_Meta_Box_Helper' ) ) {
59
RWMB_Field::call( 'show', $field, true, 0 );
60
$output = ob_get_clean();
61
62
- if ( preg_match( '!class=".*?(required).*?"!', $output, $matches ) ) {
63
- $output = str_replace( $matches[0], preg_replace( '!required!', '', $matches[0] ), $output );
64
}
65
echo $output;
66
RWMB_Field::call( 'add_actions', $field );
59
RWMB_Field::call( 'show', $field, true, 0 );
60
$output = ob_get_clean();
61
62
+ if ( preg_match( '/class="(.*)"/iSU', $output, $matches ) ) {
63
+ if ( preg_match( '/required/', $matches[0] ) ) {
64
+ $class = preg_replace( '/\s+/', ' ', str_replace( 'required', '', $matches[0] ) );
65
+ $output = preg_replace( '/class="(.*)"/iSU', $class, $output );
66
+ }
67
}
68
echo $output;
69
RWMB_Field::call( 'add_actions', $field );
inc/admin/settings/abstract-settings-page.php CHANGED
@@ -30,7 +30,6 @@ class LP_Abstract_Settings_Page extends LP_Abstract_Settings {
30
* Constructor
31
*/
32
public function __construct() {
33
-
34
}
35
36
/**
@@ -75,7 +74,7 @@ class LP_Abstract_Settings_Page extends LP_Abstract_Settings {
75
return preg_replace( array( '!\[|(\]\[)!', '!\]!' ), array( '_', '' ), $this->get_field_name( $name ) );
76
}
77
78
- public function get_sections(){
79
return array();
80
}
81
@@ -89,7 +88,7 @@ class LP_Abstract_Settings_Page extends LP_Abstract_Settings {
89
90
if ( ! $section ) {
91
$section = $this->get_sections();
92
- $section = array_keys($section);
93
}
94
95
settype( $section, 'array' );
30
* Constructor
31
*/
32
public function __construct() {
33
}
34
35
/**
74
return preg_replace( array( '!\[|(\]\[)!', '!\]!' ), array( '_', '' ), $this->get_field_name( $name ) );
75
}
76
77
+ public function get_sections() {
78
return array();
79
}
80
88
89
if ( ! $section ) {
90
$section = $this->get_sections();
91
+ $section = array_keys( $section );
92
}
93
94
settype( $section, 'array' );
inc/admin/settings/class-lp-settings-advanced.php CHANGED
@@ -87,6 +87,17 @@ class LP_Settings_Advanced extends LP_Abstract_Settings_Page {
87
'type' => 'yes-no',
88
'desc' => sprintf( __( 'Enable cache for static content such as content and settings of course, lesson, quiz. <a href="%s">%s</a>', 'learnpress' ), admin_url('admin.php?page=learn-press-tools&tab=cache'), __('Advanced', 'learnpress'))
89
),
90
)
91
);
92
}
87
'type' => 'yes-no',
88
'desc' => sprintf( __( 'Enable cache for static content such as content and settings of course, lesson, quiz. <a href="%s">%s</a>', 'learnpress' ), admin_url('admin.php?page=learn-press-tools&tab=cache'), __('Advanced', 'learnpress'))
89
),
90
+ array(
91
+ 'title' => __( 'Others', 'learnpress' ),
92
+ 'type' => 'heading',
93
+ ),
94
+ array(
95
+ 'title' => __( 'Enable lesson video', 'learnpress' ),
96
+ 'id' => 'enable_lesson_video',
97
+ 'default' => 'no',
98
+ 'type' => 'yes-no',
99
+ 'desc' => __( 'When this option is enabled, the first video embed in lesson content will be detected and move to the top.', 'learnpress' )
100
+ ),
101
)
102
);
103
}
inc/admin/settings/class-lp-settings-emails.php CHANGED
@@ -78,6 +78,8 @@ class LP_Settings_Emails extends LP_Abstract_Settings_Page {
78
include "email-groups/class-lp-settings-become-teacher-emails.php"
79
);
80
81
foreach ( $groups as $group ) {
82
$sections[ $group->group_id ] = $group;
83
}
78
include "email-groups/class-lp-settings-become-teacher-emails.php"
79
);
80
81
+ $groups = apply_filters( 'learn-press/email-section-classes', $groups );
82
+
83
foreach ( $groups as $group ) {
84
$sections[ $group->group_id ] = $group;
85
}
inc/admin/settings/class-lp-settings-general.php CHANGED
@@ -36,14 +36,6 @@ class LP_Settings_General extends LP_Abstract_Settings_Page {
36
$settings = apply_filters(
37
'learn-press/general-settings-fields',
38
array(
39
- /*array(
40
- 'title' => __( 'Instructors registration', 'learnpress' ),
41
- 'desc' => __( 'Create option for instructors registration.', 'learnpress' ),
42
- 'id' => 'instructor_registration',
43
- 'default' => 'no',
44
- 'type' => 'checkbox'
45
- ),*/
46
-
47
array(
48
'title' => __( 'General', 'learnpress' ),
49
'type' => 'heading',
36
$settings = apply_filters(
37
'learn-press/general-settings-fields',
38
array(
39
array(
40
'title' => __( 'General', 'learnpress' ),
41
'type' => 'heading',
inc/admin/settings/class-lp-settings-pages.php CHANGED
@@ -41,6 +41,13 @@ class LP_Settings_Pages extends LP_Abstract_Settings_Page {
41
'default' => '',
42
'type' => 'pages-dropdown'
43
),
44
),
45
$this
46
);
41
'default' => '',
42
'type' => 'pages-dropdown'
43
),
44
+ array(
45
+ 'title' => __( 'Instructors registration', 'learnpress' ),
46
+ 'desc' => __( 'Create option for instructors registration.', 'learnpress' ),
47
+ 'id' => 'instructor_registration',
48
+ 'default' => 'no',
49
+ 'type' => 'yes-no'
50
+ )
51
),
52
$this
53
);
inc/admin/sub-menus/class-lp-submenu-settings.php CHANGED
@@ -112,6 +112,7 @@ class LP_Submenu_Settings extends LP_Abstract_Submenu {
112
public function maybe_save_settings() {
113
// Verify nonce
114
$nonce = learn_press_get_request( 'lp-settings-nonce' );
115
if ( ! wp_verify_nonce( $nonce, 'lp-settings' ) ) {
116
return;
117
}
@@ -131,9 +132,11 @@ class LP_Submenu_Settings extends LP_Abstract_Submenu {
131
}
132
}
133
}
134
}
135
do_action( 'learn-press/update-settings/updated', $this );
136
- add_settings_error( 'sdfdsfsdf', 'saved', __( 'Settings saved.', 'learnpress' ), 'updated' );
137
// Filter redirect
138
$redirect = apply_filters( 'learn-press/update-settings/redirect', add_query_arg( 'settings-updated', 'yes' ), $this );
139
if ( $redirect ) {
112
public function maybe_save_settings() {
113
// Verify nonce
114
$nonce = learn_press_get_request( 'lp-settings-nonce' );
115
+
116
if ( ! wp_verify_nonce( $nonce, 'lp-settings' ) ) {
117
return;
118
}
132
}
133
}
134
}
135
+
136
+ flush_rewrite_rules();
137
}
138
do_action( 'learn-press/update-settings/updated', $this );
139
+
140
// Filter redirect
141
$redirect = apply_filters( 'learn-press/update-settings/redirect', add_query_arg( 'settings-updated', 'yes' ), $this );
142
if ( $redirect ) {
inc/admin/views/course/section.php CHANGED
@@ -31,7 +31,7 @@ learn_press_admin_view( 'course/new-section-item' );
31
<input v-model="section.description" type="text" class="description-input no-submit"
32
title="description"
33
@change="updating" @blur="completed" @keyup.enter="completed" ref="description"
34
- placeholder="<?php echo esc_attr( 'Describe about this section', 'learnpress' ); ?>">
35
</div>
36
37
<div class="section-list-items" :class="{'no-item': !section.items.length}">
31
<input v-model="section.description" type="text" class="description-input no-submit"
32
title="description"
33
@change="updating" @blur="completed" @keyup.enter="completed" ref="description"
34
+ placeholder="<?php esc_attr_e( 'Describe about this section', 'learnpress' ); ?>">
35
</div>
36
37
<div class="section-list-items" :class="{'no-item': !section.items.length}">
inc/admin/views/setup/notice-setup.php CHANGED
@@ -3,6 +3,6 @@
3
<p>
4
<a class="button"
5
href="<?php echo admin_url( 'index.php?page=lp-setup' ); ?>"><?php _e( 'Run setup wizard', 'learnpress' ); ?></a>
6
- <button class="button"><?php _e( 'Skip', 'learnpress' ); ?></button>
7
</p>
8
</div>
3
<p>
4
<a class="button"
5
href="<?php echo admin_url( 'index.php?page=lp-setup' ); ?>"><?php _e( 'Run setup wizard', 'learnpress' ); ?></a>
6
+ <button class="button" id="skip-notice-install"><?php _e( 'Skip', 'learnpress' ); ?></button>
7
</p>
8
</div>
inc/class-lp-ajax.php CHANGED
@@ -53,7 +53,7 @@ if ( ! class_exists( 'LP_AJAX' ) ) {
53
'complete-lesson',
54
'finish-course',
55
'retake-course',
56
- 'external-link'
57
//'register-user:nopriv',
58
//'login-user:nopriv'
59
);
53
'complete-lesson',
54
'finish-course',
55
'retake-course',
56
+ 'external-link:nopriv'
57
//'register-user:nopriv',
58
//'login-user:nopriv'
59
);
inc/class-lp-page-controller.php CHANGED
@@ -74,6 +74,7 @@ class LP_Page_Controller {
74
75
public function setup_data( $post ) {
76
static $courses = array();
77
78
if ( LP_COURSE_CPT !== get_post_type( $post->ID ) ) {
79
return $post;
@@ -85,12 +86,20 @@ class LP_Page_Controller {
85
86
$courses[ $post->ID ] = true;
87
88
- global $wp, $wp_query, $lp_course, $lp_course_item, $lp_quiz_question;
89
$vars = $wp->query_vars;
90
if ( empty( $vars['course-item'] ) ) {
91
return false;
92
}
93
94
try {
95
96
// If item name is set in query vars
@@ -104,19 +113,22 @@ class LP_Page_Controller {
104
105
// Post item is not exists or get it's item failed.
106
if ( ! $post_item || ( $post_item && ( ! $lp_course_item = apply_filters( 'learn-press/single-course-request-item', LP_Course_Item::get_item( $post_item->ID ) ) ) ) ) {
107
$this->set_404( true );
108
throw new Exception( __( 'You can not view this item or it does not exist!', 'learnpress' ), LP_ACCESS_FORBIDDEN_OR_ITEM_IS_NOT_EXISTS );
109
}
110
111
- $user_item_id = $lp_course->set_viewing_item( $lp_course_item );
112
113
- if ( ! $user_item_id ) {
114
return $post;
115
}
116
117
- if ( ! $lp_course->has_item( $post_item->ID ) ) {
118
- $this->set_404( true );
119
120
return $post;
121
}
122
@@ -134,7 +146,6 @@ class LP_Page_Controller {
134
throw new Exception( __( 'Invalid question!', 'learnpress' ), LP_ACCESS_FORBIDDEN_OR_ITEM_IS_NOT_EXISTS );
135
// TODO: Process in case question does not exists.
136
}
137
- //$lp_course_item->set_viewing_question( $lp_quiz_question );
138
}
139
}
140
catch ( Exception $ex ) {
@@ -241,7 +252,6 @@ class LP_Page_Controller {
241
$this->_load_archive_courses( $template );
242
}
243
}
244
-
245
return $template;
246
}
247
@@ -498,10 +508,11 @@ class LP_Page_Controller {
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
// Fixed issue with Yoast Seo plugin
504
- //$wp_query->is_category = true;
505
$wp_query->is_single = false;
506
} else {
507
$wp_query->found_posts = 1;
74
75
public function setup_data( $post ) {
76
static $courses = array();
77
+ global $wp, $wp_query, $lp_course, $lp_course_item, $lp_quiz_question;
78
79
if ( LP_COURSE_CPT !== get_post_type( $post->ID ) ) {
80
return $post;
86
87
$courses[ $post->ID ] = true;
88
89
$vars = $wp->query_vars;
90
+
91
if ( empty( $vars['course-item'] ) ) {
92
return false;
93
}
94
95
+ if ( ! $wp_query->is_main_query() ) {
96
+ return $post;
97
+ }
98
+
99
+ if ( $wp_query->queried_object_id !== $lp_course->get_id() ) {
100
+ return $post;
101
+ }
102
+
103
try {
104
105
// If item name is set in query vars
113
114
// Post item is not exists or get it's item failed.
115
if ( ! $post_item || ( $post_item && ( ! $lp_course_item = apply_filters( 'learn-press/single-course-request-item', LP_Course_Item::get_item( $post_item->ID ) ) ) ) ) {
116
+
117
$this->set_404( true );
118
throw new Exception( __( 'You can not view this item or it does not exist!', 'learnpress' ), LP_ACCESS_FORBIDDEN_OR_ITEM_IS_NOT_EXISTS );
119
}
120
121
+ // If current course does not contain the item is viewing
122
+ // then the page should become 404
123
+ if ( ! $lp_course->has_item( $post_item->ID ) ) {
124
+ $this->set_404( true );
125
126
return $post;
127
}
128
129
+ $user_item_id = $lp_course->set_viewing_item( $lp_course_item );
130
131
+ if ( ! $user_item_id ) {
132
return $post;
133
}
134
146
throw new Exception( __( 'Invalid question!', 'learnpress' ), LP_ACCESS_FORBIDDEN_OR_ITEM_IS_NOT_EXISTS );
147
// TODO: Process in case question does not exists.
148
}
149
}
150
}
151
catch ( Exception $ex ) {
252
$this->_load_archive_courses( $template );
253
}
254
}
255
return $template;
256
}
257
508
$wp_query->posts = array( $wp_query->post );
509
510
if ( is_post_type_archive( LP_COURSE_CPT ) || LEARNPRESS_IS_CATEGORY ) {
511
+ $wp_query->is_page = false;
512
+ $wp_query->is_archive = true;
513
// Fixed issue with Yoast Seo plugin
514
+ $wp_query->is_category = learn_press_is_course_category();
515
+ $wp_query->is_tax = learn_press_is_course_tax();
516
$wp_query->is_single = false;
517
} else {
518
$wp_query->found_posts = 1;
inc/class-lp-preview-course.php CHANGED
@@ -159,10 +159,6 @@ class LP_Preview_Course {
159
if ( false === ( $ids = wp_cache_get( 'preview-courses', 'learnpress' ) ) ) {
160
global $wpdb;
161
$query = $wpdb->prepare( "
162
- SELECT ID
163
- FROM {$wpdb->posts} p
164
- WHERE post_author = 0
165
- UNION
166
SELECT post_id
167
FROM {$wpdb->postmeta}
168
WHERE meta_key = %s AND meta_value = %s
159
if ( false === ( $ids = wp_cache_get( 'preview-courses', 'learnpress' ) ) ) {
160
global $wpdb;
161
$query = $wpdb->prepare( "
162
SELECT post_id
163
FROM {$wpdb->postmeta}
164
WHERE meta_key = %s AND meta_value = %s
inc/course/abstract-course.php CHANGED
@@ -843,7 +843,7 @@ if ( ! function_exists( 'LP_Abstract_Course' ) ) {
843
public function is_in_stock() {
844
$in_stock = true;
845
if ( $max_allowed = $this->get_max_students() ) {
846
- $in_stock = $max_allowed > $this->count_students();
847
}
848
849
return apply_filters( 'learn-press/is-in-stock', $in_stock, $this->get_id() );
@@ -1755,7 +1755,7 @@ if ( ! function_exists( 'LP_Abstract_Course' ) ) {
1755
}
1756
1757
public function get_external_link_text() {
1758
- return apply_filters( 'learn-press/course-external-link-text', __( 'Buy this course', 'learnpress' ), $this->get_id() );
1759
}
1760
1761
/**
843
public function is_in_stock() {
844
$in_stock = true;
845
if ( $max_allowed = $this->get_max_students() ) {
846
+ $in_stock = $max_allowed > $this->count_in_order();
847
}
848
849
return apply_filters( 'learn-press/is-in-stock', $in_stock, $this->get_id() );
1755
}
1756
1757
public function get_external_link_text() {
1758
+ return apply_filters( 'learn-press/course-external-link-text', _x( 'Buy this course','Text of Buy this course with external link', 'learnpress' ), $this->get_id() );
1759
}
1760
1761
/**
inc/curds/class-lp-question-curd.php CHANGED
@@ -1007,4 +1007,4 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
1007
// TODO: Implement update_meta() method.
1008
}
1009
}
1010
- }
1007
// TODO: Implement update_meta() method.
1008
}
1009
}
1010
+ }
inc/curds/class-lp-section-curd.php CHANGED
@@ -246,6 +246,9 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
246
public function sort_sections( $sections ) {
247
global $wpdb;
248
249
$orders = array();
250
251
foreach ( $sections as $index => $section_id ) {
@@ -258,8 +261,18 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
258
array( 'section_order' => $order ),
259
array( 'section_id' => $section_id )
260
);
261
}
262
263
return $orders;
264
}
265
@@ -277,18 +290,21 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
277
278
$sections = $course->get_curriculum_raw();
279
280
- if ( empty( $sections ) ) {
281
- return array();
282
- }
283
- foreach ( $sections as $section ) {
284
- if ( $section['id'] == $section_id ) {
285
- if ( isset( $section['items'] ) && is_array( $section['items'] ) ) {
286
- return $section['items'];
287
}
288
}
289
}
290
291
- return array();
292
}
293
294
/**
@@ -434,27 +450,49 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
434
}
435
436
/**
437
- * Update course final quiz.
438
*
439
* @since 3.0.0
440
*
441
- * @param $section_id
442
- *
443
* @return bool
444
*/
445
- public function update_final_quiz( $section_id ) {
446
447
// get last section items
448
- $section_items = $this->get_section_items( $section_id );
449
450
if ( $section_items ) {
451
// last item in last section
452
$final = end( $section_items );
453
454
- if ( $final['type'] == LP_QUIZ_CPT ) {
455
- update_post_meta( $this->course_id, '_lp_final_quiz', $final['id'] );
456
} else {
457
- delete_post_meta( $this->course_id, '_lp_final_quiz' );
458
}
459
}
460
@@ -462,10 +500,6 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
462
463
}
464
465
- public function sort_section_items( $orders ) {
466
-
467
- }
468
-
469
/**
470
* Remove section item.
471
*
@@ -551,6 +585,8 @@ class LP_Section_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
551
}
552
}
553
554
return $items;
555
}
556
246
public function sort_sections( $sections ) {
247
global $wpdb;
248
249
+ $current_sections = wp_cache_get( 'course-' . $this->course_id, 'lp-course-sections' );
250
+ $new_sections = array();
251
+
252
$orders = array();
253
254
foreach ( $sections as $index => $section_id ) {
261
array( 'section_order' => $order ),
262
array( 'section_id' => $section_id )
263
);
264
+
265
+ foreach ( $current_sections as $current_section ) {
266
+ if ( $current_section->section_id == $section_id ) {
267
+ $new_sections[ $index ] = $current_section;
268
+ }
269
+ }
270
+
271
+ $this->get_section_items( $section_id );
272
}
273
274
+ wp_cache_set( 'course-' . $this->course_id, $new_sections, 'lp-course-sections' );
275
+
276
return $orders;
277
}
278
290
291
$sections = $course->get_curriculum_raw();
292
293
+ $return = array();
294
+
295
+ if ( ! empty( $sections ) ) {
296
+ foreach ( $sections as $section ) {
297
+ if ( $section['id'] == $section_id ) {
298
+ if ( isset( $section['items'] ) && is_array( $section['items'] ) ) {
299
+ $return = $section['items'];
300
+ }
301
}
302
}
303
}
304
305
+ wp_cache_set( 'course-' . $this->course_id . '-' . $section_id, $return, 'lp-course-section-items' );
306
+
307
+ return $return;
308
}
309
310
/**
450
}
451
452
/**
453
+ * Update course final item.
454
*
455
* @since 3.0.0
456
*
457
* @return bool
458
*/
459
+ public function update_final_item() {
460
+
461
+ $sections = wp_cache_get( 'course-' . $this->course_id, 'lp-course-sections' );
462
+
463
+ if ( ! $sections ) {
464
+ return false;
465
+ }
466
+
467
+ $last_section = end( $sections );
468
+ $section_id = $last_section->section_id;
469
470
// get last section items
471
+ $section_items = wp_cache_get( 'course-' . $this->course_id . '-' . $section_id, 'lp-course-section-items' );
472
+
473
+ $types = apply_filters( 'learn-press/post-types-support-assessment-by-final-item', array( LP_QUIZ_CPT ) );
474
475
if ( $section_items ) {
476
// last item in last section
477
$final = end( $section_items );
478
479
+ if ( is_array( $types ) && in_array( $final['type'], $types ) ) {
480
+ update_post_meta( $this->course_id, '_' . substr_replace( $final['type'], "_final_", 2, 1 ), $final['id'] );
481
+ $diff = array_diff( $types, array( $final['type'] ) );
482
+ foreach ( $diff as $type ) {
483
+ // delete all other final meta
484
+ delete_post_meta( $this->course_id, '_' . substr_replace( $type, "_final_", 2, 1 ) );
485
+ }
486
} else {
487
+ // for last item is not post type need check final item
488
+ foreach ( $types as $type ) {
489
+ delete_post_meta( $this->course_id, '_' . substr_replace( $type, "_final_", 2, 1 ) );
490
+ }
491
+ }
492
+ } else {
493
+ // for last section does not has any item
494
+ foreach ( $types as $type ) {
495
+ delete_post_meta( $this->course_id, '_' . substr_replace( $type, "_final_", 2, 1 ) );
496
}
497
}
498
500
501
}
502
503
/**
504
* Remove section item.
505
*
585
}
586
}
587
588
+ wp_cache_set( 'course-' . $this->course_id . '-' . $section_id, $items, 'lp-course-section-items' );
589
+
590
return $items;
591
}
592
inc/custom-post-types/course.php CHANGED
@@ -262,10 +262,10 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
262
* Update all course items if set Course Author option
263
*/
264
$course = learn_press_get_course( $course_id );
265
- $post_author = $_POST['_lp_course_author'];
266
267
if ( ! $curriculum = $course->get_items() ) {
268
- if ( ! empty( $post_author ) ) {
269
$wpdb->update(
270
$wpdb->posts,
271
array( 'post_author' => $post_author ),
@@ -295,7 +295,7 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
295
$ids = array_merge( (array) $course_id, $item_ids, $question_ids );
296
297
// update post author
298
- if ( ! empty( $post_author ) ) {
299
foreach ( $ids as $id ) {
300
$wpdb->update(
301
$wpdb->posts,
@@ -581,7 +581,7 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
581
'name' => __( 'Block Lessons Content', 'learnpress' ),
582
'id' => '_lp_block_lesson_content',
583
'type' => 'yes_no',
584
- 'desc' => __( 'Block lessons content when course expired.', 'learnpress' ),
585
'std' => 'no',
586
),
587
array(
@@ -1169,7 +1169,7 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
1169
private function _update_price() {
1170
global $wpdb, $post;
1171
$request = $_POST;
1172
- $price = floatval( $request['_lp_price'] );
1173
$sale_price = LP_Request::get( '_lp_sale_price' );
1174
$sale_price_start = LP_Request::get( '_lp_sale_start' );
1175
$sale_price_end = LP_Request::get( '_lp_sale_end' );
@@ -1289,7 +1289,6 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
1289
$items = wp_cache_get( 'course-' . $post->ID, 'lp-course-items' );
1290
1291
$number_lessons = $number_quizzes = 0;
1292
-
1293
if ( $items ) {
1294
foreach ( $items as $item_id ) {
1295
if ( get_post_type( $item_id ) == LP_LESSON_CPT ) {
@@ -1305,6 +1304,8 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
1305
$output .= $number_lessons ? sprintf( _n( '%d lesson', '%d lessons', $number_lessons, 'learnpress' ), $number_lessons ) : __( "0 lesson", 'learnpress' );
1306
$output .= ', ';
1307
$output .= $number_quizzes ? sprintf( _n( '%d quiz', '%d quizzes', $number_quizzes, 'learnpress' ), $number_quizzes ) : __( "0 quiz", 'learnpress' );
1308
$output .= ')';
1309
1310
echo $output;
262
* Update all course items if set Course Author option
263
*/
264
$course = learn_press_get_course( $course_id );
265
+ $post_author = isset( $_POST['_lp_course_author'] ) ? $_POST['_lp_course_author'] : '';
266
267
if ( ! $curriculum = $course->get_items() ) {
268
+ if ( $post_author ) {
269
$wpdb->update(
270
$wpdb->posts,
271
array( 'post_author' => $post_author ),
295
$ids = array_merge( (array) $course_id, $item_ids, $question_ids );
296
297
// update post author
298
+ if ( $post_author ) {
299
foreach ( $ids as $id ) {
300
$wpdb->update(
301
$wpdb->posts,
581
'name' => __( 'Block Lessons Content', 'learnpress' ),
582
'id' => '_lp_block_lesson_content',
583
'type' => 'yes_no',
584
+ 'desc' => __( 'Block lessons content when completed course.', 'learnpress' ),
585
'std' => 'no',
586
),
587
array(
1169
private function _update_price() {
1170
global $wpdb, $post;
1171
$request = $_POST;
1172
+ $price = floatval( LP_Request::get( '_lp_price' ) );
1173
$sale_price = LP_Request::get( '_lp_sale_price' );
1174
$sale_price_start = LP_Request::get( '_lp_sale_start' );
1175
$sale_price_end = LP_Request::get( '_lp_sale_end' );
1289
$items = wp_cache_get( 'course-' . $post->ID, 'lp-course-items' );
1290
1291
$number_lessons = $number_quizzes = 0;
1292
if ( $items ) {
1293
foreach ( $items as $item_id ) {
1294
if ( get_post_type( $item_id ) == LP_LESSON_CPT ) {
1304
$output .= $number_lessons ? sprintf( _n( '%d lesson', '%d lessons', $number_lessons, 'learnpress' ), $number_lessons ) : __( "0 lesson", 'learnpress' );
1305
$output .= ', ';
1306
$output .= $number_quizzes ? sprintf( _n( '%d quiz', '%d quizzes', $number_quizzes, 'learnpress' ), $number_quizzes ) : __( "0 quiz", 'learnpress' );
1307
+ // @hook to add count extent course item type
1308
+ $output .= apply_filters( 'learn-press/course-count-items', '', $items );
1309
$output .= ')';
1310
1311
echo $output;
inc/custom-post-types/lesson.php CHANGED
@@ -334,7 +334,7 @@ if ( ! class_exists( 'LP_Lesson_Post_Type' ) ) {
334
* Display content for custom column
335
*
336
* @param string $name
337
- * @param int $post_id
338
*/
339
public function columns_content( $name, $post_id = 0 ) {
340
switch ( $name ) {
@@ -347,15 +347,8 @@ if ( ! class_exists( 'LP_Lesson_Post_Type' ) ) {
347
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $course->ID ) ), __( 'Edit', 'learnpress' ) );
348
echo "&nbsp;|&nbsp;";
349
printf( '<a href="%s">%s</a>', get_the_permalink( $course->ID ), __( 'View', 'learnpress' ) );
350
- echo "&nbsp;|&nbsp;";
351
- if ( $course_id = learn_press_get_request( 'filter_course' ) ) {
352
- printf( '<a href="%s">%s</a>', remove_query_arg( 'filter_course' ), __( 'Remove Filter', 'learnpress' ) );
353
- } else {
354
- printf( '<a href="%s">%s</a>', add_query_arg( 'filter_course', $course->ID ), __( 'Filter', 'learnpress' ) );
355
- }
356
echo '</div></div>';
357
}
358
-
359
} else {
360
_e( 'Not assigned yet', 'learnpress' );
361
}
334
* Display content for custom column
335
*
336
* @param string $name
337
+ * @param int $post_id
338
*/
339
public function columns_content( $name, $post_id = 0 ) {
340
switch ( $name ) {
347
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $course->ID ) ), __( 'Edit', 'learnpress' ) );
348
echo "&nbsp;|&nbsp;";
349
printf( '<a href="%s">%s</a>', get_the_permalink( $course->ID ), __( 'View', 'learnpress' ) );
350
echo '</div></div>';
351
}
352
} else {
353
_e( 'Not assigned yet', 'learnpress' );
354
}
inc/custom-post-types/question.php CHANGED
@@ -357,12 +357,6 @@ if ( ! class_exists( 'LP_Question_Post_Type' ) ) {
357
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $quiz->ID ) ), __( 'Edit', 'learnpress' ) );
358
echo "&nbsp;|&nbsp;";
359
printf( '<a href="%s">%s</a>', get_the_permalink( $quiz->ID ), __( 'View', 'learnpress' ) );
360
- echo "&nbsp;|&nbsp;";
361
- if ( $quiz_id = learn_press_get_request( 'filter_quiz' ) ) {
362
- printf( '<a href="%s">%s</a>', remove_query_arg( 'filter_quiz' ), __( 'Remove Filter', 'learnpress' ) );
363
- } else {
364
- printf( '<a href="%s">%s</a>', add_query_arg( 'filter_quiz', $quiz->ID ), __( 'Filter', 'learnpress' ) );
365
- }
366
echo '</div></div>';
367
} else {
368
_e( 'Not assigned yet', 'learnpress' );
357
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $quiz->ID ) ), __( 'Edit', 'learnpress' ) );
358
echo "&nbsp;|&nbsp;";
359
printf( '<a href="%s">%s</a>', get_the_permalink( $quiz->ID ), __( 'View', 'learnpress' ) );
360
echo '</div></div>';
361
} else {
362
_e( 'Not assigned yet', 'learnpress' );
inc/custom-post-types/quiz.php CHANGED
@@ -353,7 +353,7 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
353
* Display content for custom column
354
*
355
* @param string $name
356
- * @param int $post_id
357
*/
358
public function columns_content( $name, $post_id = 0 ) {
359
global $post;
@@ -367,13 +367,6 @@ if ( ! class_exists( 'LP_Quiz_Post_Type' ) ) {
367
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $course->ID ) ), __( 'Edit', 'learnpress' ) );
368
echo "&nbsp;|&nbsp;";
369
printf( '<a href="%s">%s</a>', get_the_permalink( $course->ID ), __( 'View', 'learnpress' ) );
370
- echo "&nbsp;|&nbsp;";
371
- if ( $this->_filter_course() ) {
372
- printf( '<a href="%s">%s</a>', remove_query_arg( 'filter_course' ), __( 'Remove Filter', 'learnpress' ) );
373
- } else {
374
- printf( '<a href="%s">%s</a>', add_query_arg( 'filter_course', $course->ID ), __( 'Filter', 'learnpress' ) );
375
- }
376
-
377
echo '</div></div>';
378
}
379
353
* Display content for custom column
354
*
355
* @param string $name
356
+ * @param int $post_id
357
*/
358
public function columns_content( $name, $post_id = 0 ) {
359
global $post;
367
printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $course->ID ) ), __( 'Edit', 'learnpress' ) );
368
echo "&nbsp;|&nbsp;";
369
printf( '<a href="%s">%s</a>', get_the_permalink( $course->ID ), __( 'View', 'learnpress' ) );
370
echo '</div></div>';
371
}
372
inc/debug.php CHANGED
@@ -7,9 +7,20 @@
7
* use http://example.com?debug=yes to execute the code in this file
8
*/
9
10
11
- //add_action( 'plugins_loaded', function ( ) {
12
- // include_once 'updates/learnpress-update-3.0.0.php';
13
- // LP_Update_30::upgrade_orders();
14
- //}, 100000 );
15
7
* use http://example.com?debug=yes to execute the code in this file
8
*/
9
10
+ class LP_Unit_Test {
11
+ public static function init() {
12
+ add_action( 'get_header', array( __CLASS__, 'test_emails' ) );
13
+ }
14
15
+ public static function test_emails() {
16
+ global $wp_rewrite;
17
+ $emailer = LP_Emails::instance();
18
+ $email = $emailer->emails['LP_Email_Completed_Order_User'];
19
+ $email->enable = true;
20
+ $email->trigger( 2147 );
21
+ learn_press_debug($email);
22
+ die();
23
+ }
24
+ }
25
26
+ LP_Unit_Test::init();
inc/emails/class-lp-email-become-an-instructor.php CHANGED
@@ -55,7 +55,7 @@ if ( ! class_exists( 'LP_Email_Become_An_Instructor' ) ) {
55
56
LP_Emails::instance()->set_current( $this->id );
57
58
- $this->recipient = get_option( 'admin_email' );
59
60
$this->get_object( null, array(
61
'request_email' => $email
55
56
LP_Emails::instance()->set_current( $this->id );
57
58
+ $this->recipient = $this->_get_admin_email();// get_option( 'admin_email' );
59
60
$this->get_object( null, array(
61
'request_email' => $email
inc/emails/class-lp-email-cancelled-order-admin.php CHANGED
@@ -30,7 +30,7 @@ if ( ! class_exists( 'LP_Email_Cancelled_Order_Admin' ) ) {
30
$this->default_subject = __( 'Order placed on {{order_date}} has been cancelled', 'learnpress' );
31
$this->default_heading = __( 'User order has been cancelled', 'learnpress' );
32
33
- $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', get_option( 'admin_email' ) );
34
35
parent::__construct();
36
30
$this->default_subject = __( 'Order placed on {{order_date}} has been cancelled', 'learnpress' );
31
$this->default_heading = __( 'User order has been cancelled', 'learnpress' );
32
33
+ $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', $this->_get_admin_email() );
34
35
parent::__construct();
36
inc/emails/class-lp-email-completed-order-user.php CHANGED
@@ -71,12 +71,14 @@ if ( ! class_exists( 'LP_Email_Completed_Order_User' ) ) {
71
72
// disable for enroll free course
73
if ( $free == sizeof( $items ) ) {
74
return false;
75
}
76
77
$this->recipient = $order->get_user_email();
78
79
if ( ! $this->recipient ) {
80
return false;
81
}
82
71
72
// disable for enroll free course
73
if ( $free == sizeof( $items ) ) {
74
+
75
return false;
76
}
77
78
$this->recipient = $order->get_user_email();
79
80
if ( ! $this->recipient ) {
81
+
82
return false;
83
}
84
inc/emails/class-lp-email-enrolled-course-admin.php CHANGED
@@ -24,13 +24,13 @@ if ( ! class_exists( 'LP_Email_Enrolled_Course_Admin' ) ) {
24
* LP_Email_Enrolled_Course_Admin constructor.
25
*/
26
public function __construct() {
27
- $this->id = 'enrolled-course-admin';
28
- $this->title = __( 'Admin', 'learnpress' );
29
- $this->description = __( 'Send this email to admin when user has enrolled course.', 'learnpress' );
30
$this->default_subject = __( '{{user_display_name}} has enrolled course', 'learnpress' );
31
$this->default_heading = __( 'User has enrolled course', 'learnpress' );
32
33
- $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', get_option( 'admin_email' ) );
34
35
parent::__construct();
36
}
24
* LP_Email_Enrolled_Course_Admin constructor.
25
*/
26
public function __construct() {
27
+ $this->id = 'enrolled-course-admin';
28
+ $this->title = __( 'Admin', 'learnpress' );
29
+ $this->description = __( 'Send this email to admin when user has enrolled course.', 'learnpress' );
30
$this->default_subject = __( '{{user_display_name}} has enrolled course', 'learnpress' );
31
$this->default_heading = __( 'User has enrolled course', 'learnpress' );
32
33
+ $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', $this->_get_admin_email() );
34
35
parent::__construct();
36
}
inc/emails/class-lp-email-finished-course-admin.php CHANGED
@@ -30,7 +30,7 @@ if ( ! class_exists( 'LP_Email_Finished_Course_Admin' ) ) {
30
$this->default_subject = __( '{{user_display_name}} has finished course', 'learnpress' );
31
$this->default_heading = __( 'User has finished course', 'learnpress' );
32
33
- $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', get_option( 'admin_email' ) );
34
35
parent::__construct();
36
}
30
$this->default_subject = __( '{{user_display_name}} has finished course', 'learnpress' );
31
$this->default_heading = __( 'User has finished course', 'learnpress' );
32
33
+ $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', $this->_get_admin_email() );
34
35
parent::__construct();
36
}
inc/emails/class-lp-email-new-course.php CHANGED
@@ -96,7 +96,7 @@ if ( ! class_exists( 'LP_Email_New_Course' ) ) {
96
public function get_recipient() {
97
$recipient = $this->recipient;
98
if ( ! $recipient ) {
99
- $recipient = get_option( 'admin_email' );
100
}
101
$this->recipient = $recipient;
102
96
public function get_recipient() {
97
$recipient = $this->recipient;
98
if ( ! $recipient ) {
99
+ $recipient = $this->_get_admin_email();
100
}
101
$this->recipient = $recipient;
102
inc/emails/class-lp-email-new-order-admin.php CHANGED
@@ -31,7 +31,7 @@ if ( ! class_exists( 'LP_Email_New_Order_Admin' ) ) {
31
$this->default_heading = __( 'New user order', 'learnpress' );
32
33
$this->recipients = get_option( 'admin_email' );
34
- $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', $this->recipients );
35
36
parent::__construct();
37
31
$this->default_heading = __( 'New user order', 'learnpress' );
32
33
$this->recipients = get_option( 'admin_email' );
34
+ $this->recipient = LP()->settings->get( 'emails_' . $this->id . '.recipients', $this->_get_admin_email() );
35
36
parent::__construct();
37
inc/emails/class-lp-email.php CHANGED
@@ -848,7 +848,21 @@ if ( ! class_exists( 'LP_Email' ) ) {
848
$separated = apply_filters( 'learn_press_email_to_separated', false, $to, $this );
849
850
if ( ! $separated ) {
851
$return = wp_mail( $to, $subject, $message, $headers, $attachments );
852
} else {
853
if ( is_array( $to ) ) {
854
foreach ( $to as $t ) {
@@ -1102,6 +1116,10 @@ if ( ! class_exists( 'LP_Email' ) ) {
1102
return $instructors;
1103
}
1104
1105
/**
1106
* @return string
1107
*/
848
$separated = apply_filters( 'learn_press_email_to_separated', false, $to, $this );
849
850
if ( ! $separated ) {
851
+ if ( ! empty( $_REQUEST['debug'] ) ) {
852
+ ob_start();
853
+ learn_press_debug( get_option( 'active_plugins' ) );
854
+ $message .= "======" . ob_get_clean();
855
+ }
856
$return = wp_mail( $to, $subject, $message, $headers, $attachments );
857
+
858
+ if ( ! empty( $_REQUEST['debug'] ) ) {
859
+ echo "[", get_class( $this ), " = {$return}]";
860
+ print_r( $to );
861
+ print_r( $subject );
862
+ print_r( $message );
863
+ print_r( $headers );
864
+ print_r( $attachments );
865
+ }
866
} else {
867
if ( is_array( $to ) ) {
868
foreach ( $to as $t ) {
1116
return $instructors;
1117
}
1118
1119
+ protected function _get_admin_email() {
1120
+ return apply_filters( 'learn-press/email/admin-email', get_option( 'admin_email' ) );
1121
+ }
1122
+
1123
/**
1124
* @return string
1125
*/
inc/libraries/meta-box/css/background.css ADDED
@@ -0,0 +1,17 @@
1
+ .rwmb-background-row {
2
+ margin-bottom: 5px;
3
+ }
4
+ .rwmb-background-wrapper .wp-picker-container {
5
+ position: relative;
6
+ display: inline-block;
7
+ vertical-align: top;
8
+ }
9
+ .rwmb-background-wrapper .wp-picker-holder {
10
+ position: absolute;
11
+ z-index: 9;
12
+ min-width: 255px;
13
+ }
14
+ .rwmb-background-wrapper .rwmb-select {
15
+ width: 49%;
16
+ max-width: 230px;
17
+ }
inc/libraries/meta-box/css/button-group.css ADDED
@@ -0,0 +1,68 @@
1
+ .rwmb-button-input-list li {
2
+ margin-bottom: 0;
3
+ list-style: none;
4
+ }
5
+ .rwmb-button-input-list .rwmb-button_group {
6
+ display: none;
7
+ }
8
+ .rwmb-button-input-list li label {
9
+ display: inline-block;
10
+ border: #ccc solid 1px;
11
+ position: relative;
12
+ z-index: 1;
13
+ padding: 5px 10px;
14
+ background: #fff;
15
+ }
16
+ .rwmb-button-input-list li label.selected {
17
+ border-color: #0073aa;
18
+ background: #0073aa;
19
+ color: #fff;
20
+ z-index: 2;
21
+ }
22
+ /* Layout not inline
23
+ -------------------------------------------------*/
24
+ .rwmb-button-input-list:not(.inline) li label {
25
+ border-top-width: 0;
26
+ }
27
+ .rwmb-button-input-list:not(.inline) li:first-child label {
28
+ border-top-width: 1px;
29
+ }
30
+ .rwmb-button-input-list:not(.inline) li label.selected {
31
+ border-bottom: 1px solid #fff;
32
+ }
33
+ .rwmb-button-input-list:not(.inline) li:last-child label.selected {
34
+ border-bottom-color: #0073aa;
35
+ }
36
+ .rwmb-button-input-list:not(.inline) > li:first-child:not(:last-child) label {
37
+ border-top-left-radius: 3px;
38
+ border-top-right-radius: 3px;
39
+ }
40
+ .rwmb-button-input-list:not(.inline) > li:last-child:not(:first-child) label {
41
+ border-bottom-right-radius: 3px;
42
+ border-bottom-left-radius: 3px;
43
+ }
44
+ /* Layout inline
45
+ ---------------------------------------------*/
46
+ .rwmb-button-input-list.inline li {
47
+ display: inline-block;
48
+ }
49
+ .rwmb-button-input-list.inline li label {
50
+ border-left-width: 0;
51
+ }
52
+ .rwmb-button-input-list.inline li:first-child label {
53
+ border-left-width: 1px;
54
+ }
55
+ .rwmb-button-input-list.inline li label.selected {
56
+ border-right-color: rgb(255, 255, 255);
57
+ }
58
+ .rwmb-button-input-list.inline li:last-child label.selected {
59
+ border-right-color: #0073aa;
60
+ }
61
+ .rwmb-button-input-list.inline > li:first-child:not(:last-child) label {
62
+ border-top-left-radius: 3px;
63
+ border-bottom-left-radius: 3px;
64
+ }
65
+ .rwmb-button-input-list.inline > li:last-child:not(:first-child) label {
66
+ border-top-right-radius: 3px;
67
+ border-bottom-right-radius: 3px;
68
+ }
inc/libraries/meta-box/css/fieldset-text.css ADDED
@@ -0,0 +1,4 @@
1
+ .rwmb-fieldset_text-wrapper fieldset label {
2
+ width: 20%;
3
+ display: inline-block;
4
+ }
inc/libraries/meta-box/css/file-input.css ADDED
@@ -0,0 +1,6 @@
1
+ .rwmb-file_input.rwmb-file_input {
2
+ line-height: 18px;
3
+ margin: 0;
4
+ padding: 4px;
5
+ width: 300px;
6
+ }
inc/libraries/meta-box/css/switch.css ADDED
@@ -0,0 +1,94 @@
1
+ /* style switch
2
+ -----------------------------*/
3
+ .rwmb-switch-label {
4
+ position: relative;
5
+ display: inline-block;
6
+ background-color: #ccc;
7
+ padding: 2px;
8
+ border-radius: 3px;
9
+ min-width: 40px;
10
+ height: 22px;
11
+ box-sizing: border-box;
12
+ }
13
+
14
+ .rwmb-switch.rwmb-switch {
15
+ display: none;
16
+ }
17
+
18
+ .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider {
19
+ background-color: #0073aa;
20
+ box-shadow: 0 0 1px #0073aa;
21
+ }
22
+
23
+ .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-slider:before {
24
+ left: calc(100% - 20px);
25
+ }
26
+
27
+ .rwmb-switch:checked + .rwmb-switch-status .rwmb-switch-off {
28
+ visibility: hidden;
29
+ display: none;
30
+ }
31
+
32
+ .rwmb-switch:not(:checked) + .rwmb-switch-status .rwmb-switch-on {
33
+ visibility: hidden;
34
+ display: none;
35
+ }
36
+
37
+ .rwmb-switch-slider {
38
+ position: absolute;
39
+ cursor: pointer;
40
+ top: 0;
41
+ left: 0;
42
+ right: 0;
43
+ bottom: 0;
44
+ z-index: 15;
45
+ -webkit-transition: .4s;
46
+ transition: .4s;
47
+ }
48
+
49
+ .rwmb-switch-slider:before {
50
+ position: absolute;
51
+ content: attr(title-before) "";
52
+ height: 18px;
53
+ width: 18px;
54
+ left: 2px;
55
+ bottom: 2px;
56
+ z-index: 99;
57
+ background-color: white;
58
+ -webkit-transition: .4s;
59
+ transition: .4s;
60
+ border-radius: 2px;
61
+ }
62
+
63
+ .rwmb-switch-label--square .rwmb-switch-slider {
64
+ border-radius: 3px;
65
+ }
66
+
67
+ .rwmb-switch-label--rounded,
68
+ .rwmb-switch-label--rounded .rwmb-switch-slider {
69
+ border-radius: 34px;
70
+ }
71
+
72
+ .rwmb-switch-label--rounded .rwmb-switch-slider:before {
73
+ border-radius: 50%;
74
+ }
75
+
76
+ .rwmb-switch-on,
77
+ .rwmb-switch-off {
78
+ display: inline-block;
79
+ float: left;
80
+ margin: 0 4px;
81
+ color: #fff;
82
+ text-transform: uppercase;
83
+ font-size: 11px;
84
+ position: relative;
85
+ z-index: 20;
86
+ }
87
+
88
+ .rwmb-switch-on {
89
+ padding-right: 20px;
90
+ }
91
+
92
+ .rwmb-switch-off {
93
+ padding-left: 20px;
94
+ }
inc/libraries/meta-box/inc/about/about.php ADDED
@@ -0,0 +1,125 @@
1
+ <?php
2
+ /**
3
+ * Add about page for the Meta Box plugin.
4
+ *
5
+ * @package Meta Box
6
+ */
7
+
8
+ /**
9
+ * About page class.
10
+ */
11
+ class RWMB_About {
12
+ /**
13
+ * Plugin data.
14
+ *
15
+ * @var array
16
+ */
17
+ protected $plugin;
18
+
19
+ /**
20
+ * Init hooks.
21
+ */
22
+ public function init() {
23
+ if ( ! function_exists( 'get_plugin_data' ) ) {
24
+ include ABSPATH . 'wp-admin/includes/plugin.php';
25
+ }
26
+ $this->plugin = get_plugin_data( RWMB_DIR . 'meta-box.php' );
27
+
28
+ // Add links to about page in the plugin action links.
29
+ add_filter( 'plugin_action_links_meta-box/meta-box.php', array( $this, 'plugin_links' ) );
30
+
31
+ // Add a hidden about page.
32
+ add_action( 'admin_menu', array( $this, 'register_page' ) );
33
+ add_action( 'admin_head', array( $this, 'hide_page' ) );
34
+
35
+ // Enqueue scripts and styles for about page.
36
+ add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
37
+
38
+ // Redirect to about page after activation.
39
+ add_action( 'activated_plugin', array( $this, 'redirect' ), 10, 2 );
40
+ }
41
+
42
+ /**
43
+ * Add links to About page.
44
+ *
45
+ * @param array $links Array of plugin links.
46
+ *
47
+ * @return array
48
+ */
49
+ public function plugin_links( $links ) {
50
+ $links[] = '<a href="' . esc_url( admin_url( 'index.php?page=meta-box-about' ) ) . '">' . esc_html__( 'About', 'meta-box' ) . '</a>';
51
+ return $links;
52
+ }
53
+
54
+ /**
55
+ * Register admin page.
56
+ */
57
+ public function register_page() {
58
+ add_dashboard_page(
59
+ __( 'Welcome to Meta Box', 'meta-box' ),
60
+ __( 'Welcome to Meta Box', 'meta-box' ),
61
+ 'activate_plugins',
62
+ 'meta-box-about',
63
+ array( $this, 'render' )
64
+ );
65
+ }
66
+
67
+ /**
68
+ * Hide about page from the admin menu.
69
+ */
70
+ public function hide_page() {
71
+ remove_submenu_page( 'index.php', 'meta-box-about' );
72
+ }
73
+
74
+ /**
75
+ * Render admin page.
76
+ */
77
+ public function render() {
78
+ ?>
79
+ <div class="wrap about-wrap">
80
+ <?php include dirname( __FILE__ ) . '/sections/welcome.php'; ?>
81
+ <?php include dirname( __FILE__ ) . '/sections/tabs.php'; ?>
82
+ <?php include dirname( __FILE__ ) . '/sections/getting-started.php'; ?>
83
+ </div>
84
+ <?php
85
+ }
86
+
87
+ /**
88
+ * Enqueue CSS and JS.
89
+ */
90
+ public function enqueue() {
91
+ $screen = get_current_screen();
92
+ if ( 'dashboard_page_meta-box-about' !== $screen->id ) {
93
+ return;
94
+ }
95
+ wp_enqueue_style( 'meta-box-about', RWMB_URL . 'inc/about/css/style.css' );
96
+ wp_enqueue_script( 'meta-box-about', RWMB_URL . 'inc/about/js/script.js', array( 'jquery' ), '', true );
97
+ }
98
+
99
+ /**
100
+ * Redirect to about page after Meta Box has been activated.
101
+ *
102
+ * @param string $plugin Path to the main plugin file from plugins directory.
103
+ * @param bool $network_wide Whether to enable the plugin for all sites in the network
104
+ * or just the current site. Multisite only. Default is false.
105
+ */
106
+ public function redirect( $plugin, $network_wide ) {
107
+ if ( ! $network_wide && 'meta-box/meta-box.php' === $plugin && ! $this->is_bundled() ) {
108
+ wp_safe_redirect( admin_url( 'index.php?page=meta-box-about' ) );
109
+ die;
110
+ }
111
+ }
112
+
113
+ /**
114
+ * Check if Meta Box is bundled by TGM Activation Class.
115
+ */
116
+ protected function is_bundled() {
117
+ // @codingStandardsIgnoreLine
118
+ foreach ( $_REQUEST as $key => $value ) {
119
+ if ( false !== strpos( $key, 'tgmpa' ) || false !== strpos( $value, 'tgmpa' ) ) {
120
+ return true;
121
+ }
122
+ }
123
+ return false;
124
+ }
125
+ }
inc/libraries/meta-box/inc/about/css/style.css ADDED
@@ -0,0 +1,57 @@
1
+ .about-wrap .wp-badge {
2
+ background-image: url(../images/meta-box.png);
3
+ background-color: #fff;
4
+ color: #222;
5
+ text-transform: uppercase;
6
+ font-weight: bold;
7
+ text-decoration: none;
8
+ }
9
+
10
+ .wp-badge:hover {
11
+ text-decoration: none;
12
+ }
13
+
14
+ .feature-section.two-col {
15
+ align-items: flex-start;
16
+ }
17
+
18
+ .feature-section.two-col h3:not(:first-child) {
19
+ margin-top: 3em;
20
+ }
21
+
22
+ .feature-section img {
23
+ display: block;
24
+ box-shadow: 0 0 20px rgba(0, 0, 0, .1);
25
+ }
26
+
27
+ .nav-tab-active:focus {
28
+ box-shadow: none;
29
+ }
30
+
31
+ .gt-tab-pane {
32
+ display: none;
33
+ }
34
+
35
+ .gt-is-active {
36
+ display: block;
37
+ }
38
+
39
+ .screenshot {
40
+ display: block;
41
+ margin: 3em auto;
42
+ }
43
+ .col ul {
44
+ font-size: 14px;
45
+ margin: 2em 0;
46
+ }
47
+
48
+ .col li a {
49
+ text-decoration: none;
50
+ }
51
+
52
+ .col .dashicons {
53
+ color: #82878c;
54
+ padding-right: 5px;
55
+ font-size: 16px;
56
+ vertical-align: middle;
57
+ }
inc/libraries/meta-box/inc/about/images/meta-box.png ADDED
Binary file
inc/libraries/meta-box/inc/about/images/online-generator.png ADDED
Binary file
inc/libraries/meta-box/inc/about/js/script.js ADDED
@@ -0,0 +1,22 @@
1
+ ( function ( $ ) {
2
+ 'use strict';
3
+
4
+ function tabs() {
5
+ var $container = $( '.nav-tab-wrapper' ),
6
+ $tabs = $container.find( '.nav-tab' ),
7
+ $panes = $( '.gt-tab-pane' );
8
+
9
+ $container.on( 'click', '.nav-tab', function ( e ) {
10
+ e.preventDefault();
11
+
12
+ $tabs.removeClass( 'nav-tab-active' );
13
+ $( this ).addClass( 'nav-tab-active' );
14
+
15
+ $panes.removeClass( 'gt-is-active' );
16
+ $panes.filter( $( this ).attr( 'href' ) ).addClass( 'gt-is-active' );
17
+ } );
18
+ }
19
+
20
+ // Auto activate tabs when DOM ready.
21
+ $( tabs );
22
+ } ( jQuery ) );
inc/libraries/meta-box/inc/about/sections/getting-started.php ADDED
@@ -0,0 +1,41 @@
1
+ <?php
2
+ /**
3
+ * Getting started section.
4
+ *
5
+ * @package Meta Box
6
+ * @subpackage MB Custom Post Type
7
+ */
8
+
9
+ ?>
10
+ <div id="getting-started" class="gt-tab-pane gt-is-active">
11
+ <div class="feature-section two-col">
12
+ <div class="col">
13
+ <h3><?php esc_html_e( 'Getting Started With Online Generator', 'meta-box' ); ?></h3>
14
+ <p><?php esc_html_e( 'The fastest way to getting started with Meta Box is use our online generator to generate meta boxes with custom fields. It provides a friendly UI for you to create meta boxes and custom fields just by drag and drop fields.', 'meta-box' ); ?><p>
15
+
16
+ <a class="screenshot" href="https://metabox.io/online-generator/?utm_source=plugin_about_page&utm_medium=link_generator&utm_campaign=meta_box_about_page" target="_blank"><img src="<?php echo esc_url( RWMB_URL . 'inc/about/images/online-generator.png' ); ?>" alt="<?php esc_attr_e( 'online generator', 'meta-box' ); ?>"></a>
17
+
18
+ <p><a href="<?php echo esc_url( 'https://metabox.io/online-generator/?utm_source=plugin_about_page&utm_medium=button_generator&utm_campaign=meta_box_about_page' ); ?>" class="button button-primary"><?php esc_html_e( 'Go to Online Generator', 'meta-box' ); ?></a></p>
19
+ </div>
20
+
21
+ <div class="col">
22
+ <h3><?php esc_html_e( 'Understand The Basics', 'meta-box' ); ?></h3>
23
+ <p><?php esc_html_e( 'Meta Box doesn\'t have any admin page for configuration or settings. Instead of that, it provides a very powerful API to speed up the process of creating meta boxes and custom fields. It might take you a little time at first, but then you\'ll love the way it work because it helps you do and customize almost everything.', 'meta-box' ); ?><p>
24
+ <p><a href="<?php echo esc_url( 'https://docs.metabox.io/quick-start/?utm_source=plugin_about_page&utm_medium=button_docs&utm_campaign=meta_box_about_page' ); ?>" class="button button-primary"><?php esc_html_e( 'Learn More', 'meta-box' ); ?></a></p>
25
+
26
+ <h3><?php esc_html_e( 'Extensions', 'meta-box' ); ?></h3>
27
+ <p><?php esc_html_e( 'Wanna see more features that transform your WordPress website into a powerful CMS? Check out some extensions below:', 'meta-box' ); ?><p>
28
+ <ul>
29
+ <li><a target="_blank" href="https://metabox.io/plugins/meta-box-group/?utm_source=plugin_about_page&utm_medium=link_group&utm_campaign=meta_box_about_page"><span class="dashicons dashicons-welcome-widgets-menus"></span> <?php esc_html_e( 'Meta Box Group', 'meta-box' ); ?></a></li>
30
+ <li><a target="_blank" href="https://metabox.io/plugins/meta-box-conditional-logic/?utm_source=plugin_about_page&utm_medium=link_conditional&utm_campaign=meta_box_about_page"><span class="dashicons dashicons-yes"></span> <?php esc_html_e( 'Meta Box Conditional Logic', 'meta-box' ); ?></a></li>
31
+ <li><a target="_blank" href="https://metabox.io/plugins/mb-settings-page/?utm_source=plugin_about_page&utm_medium=link_settings&utm_campaign=meta_box_about_page"><span class="dashicons dashicons-admin-generic"></span> <?php esc_html_e( 'MB Settings Page', 'meta-box' ); ?></a></li>
32
+ <li><a target="_blank" href="https://metabox.io/plugins/mb-term-meta/?utm_source=plugin_about_page&utm_medium=link_term&utm_campaign=meta_box_about_page"><span class="dashicons dashicons-image-filter"></span> <?php esc_html_e( 'MB Term Meta', 'meta-box' ); ?></a></li>
33
+ </ul>
34
+ <p><a target="_blank" class="button button-primary" href="https://metabox.io/plugins/?utm_source=plugin_about_page&utm_medium=button_extensions&utm_campaign=meta_box_about_page"><?php esc_html_e( 'More Extensions', 'meta-box' ); ?></a>
35
+ </div>
36
+ </div>
37
+ <hr>
38
+ <div class="return-to-dashboard">
39
+ <a href="https://metabox.io/plugins/?utm_source=plugin_about_page&utm_medium=link_home&utm_campaign=meta_box_about_page"><?php esc_html_e( 'Go to MetaBox.IO &rarr;', 'meta-box' ); ?></a>
40
+ </div>
41
+ </div>
inc/libraries/meta-box/inc/about/sections/tabs.php ADDED
@@ -0,0 +1,12 @@
1
+ <?php
2
+ /**
3
+ * Tabs navigation.
4
+ *
5
+ * @package Meta Box
6
+ * @subpackage MB Custom Post Type
7
+ */
8
+
9
+ ?>
10
+ <h2 class="nav-tab-wrapper">
11
+ <a href="#getting-started" class="nav-tab nav-tab-active"><?php esc_html_e( 'Getting Started', 'meta-box' ); ?></a>
12
+ </h2>
inc/libraries/meta-box/inc/about/sections/welcome.php ADDED
@@ -0,0 +1,17 @@
1
+ <?php
2
+ /**
3
+ * Welcome section.
4
+ *
5
+ * @package Meta Box
6
+ * @subpackage MB Custom Post Type
7
+ */
8
+
9
+ ?>
10
+ <h1>
11
+ <?php
12
+ // Translators: %1$s - Plugin name, %2$s - Plugin version.
13
+ echo esc_html( sprintf( __( 'Welcome to %1$s %2$s', 'meta-box' ), $this->plugin['Name'], $this->plugin['Version'] ) );
14
+ ?>
15
+ </h1>
16
+ <div class="about-text"><?php esc_html_e( 'This plugin is a lightweight and powerful toolkit that helps you to create custom meta boxes and custom fields in WordPress fast and easy. Follow the instruction below to get started.', 'meta-box' ); ?></div>
17
+ <a target="_blank" href="<?php echo esc_url( 'https://metabox.io/?utm_source=plugin_about_page&utm_medium=badge_link&utm_campaign=meta_box_about' ); ?>" class="wp-badge"><?php echo esc_html( $this->plugin['Name'] ); ?></a>
inc/libraries/meta-box/inc/storages/base.php ADDED
@@ -0,0 +1,98 @@