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 @@