LearnPress – WordPress LMS Plugin - Version 3.0.9

Version Description

  • GDPR compliance ~ Improved Start quiz button ~ Load js for comment-reply if it does not load by default ~ Fixed missing param when sending email for user who finished course
Download this release

Release Info

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

Code changes from version 3.0.8 to 3.0.9

Files changed (48) hide show
  1. assets/css/admin/admin.css +11 -0
  2. assets/js/admin/course-editor.js +0 -1
  3. assets/js/global.js +65 -11
  4. assets/scss/admin/_admin-editor.scss +18 -0
  5. inc/admin/class-lp-plugin-install-list-table.php +1 -1
  6. inc/admin/lp-admin-actions.php +1 -1
  7. inc/class-lp-assets.php +10 -4
  8. inc/class-lp-gdpr.php +557 -0
  9. inc/class-lp-hard-cache.php +1 -1
  10. inc/class-lp-helper.php +35 -0
  11. inc/class-lp-install.php +1 -1
  12. inc/class-lp-session-handler.php +2 -2
  13. inc/class-lp-settings.php +6 -6
  14. inc/course/abstract-course.php +17 -0
  15. inc/course/class-lp-course-item.php +22 -2
  16. inc/course/lp-course-functions.php +1 -1
  17. inc/curds/class-lp-course-curd.php +20 -0
  18. inc/curds/class-lp-order-curd.php +1 -1
  19. inc/curds/class-lp-question-curd.php +2 -2
  20. inc/curds/class-lp-user-curd.php +5 -7
  21. inc/curds/class-lp-user-item-curd.php +5 -2
  22. inc/custom-post-types/course.php +19 -7
  23. inc/custom-post-types/lesson.php +0 -17
  24. inc/emails/_bk/class-lp-email-finished-course-admin.php +199 -0
  25. inc/emails/_bk/class-lp-email-finished-course-instructor.php +201 -0
  26. inc/emails/_bk/class-lp-email-finished-course-user.php +201 -0
  27. inc/emails/types/class-lp-email-type-finished-course.php +1 -0
  28. inc/gateways/paypal/class-lp-gateway-paypal.php +1 -1
  29. inc/libraries/meta-box/css/image-advanced.css +52 -0
  30. inc/libraries/meta-box/img/loader.gif +0 -0
  31. inc/libraries/meta-box/inc/fields/thickbox-image.php +80 -0
  32. inc/libraries/meta-box/js/thickbox-image.js +34 -0
  33. inc/libraries/wp-background-process.php +1 -1
  34. inc/lp-constants.php +1 -1
  35. inc/lp-core-functions.php +1 -1
  36. inc/lp-template-functions.php +68 -18
  37. inc/order/class-lp-order.php +1 -1
  38. inc/updates/_update-from-0.9.php +2 -2
  39. inc/user-item/class-lp-user-item-course.php +2 -2
  40. inc/user-item/class-lp-user-item.php +1 -25
  41. inc/user/abstract-lp-user.php +58 -141
  42. inc/user/class-lp-profile.php +3 -1
  43. learnpress.php +5 -3
  44. readme.txt +7 -1
  45. templates/content-lesson/block-content.php +17 -0
  46. templates/content-quiz/buttons/start.php +8 -8
  47. templates/profile/content.php +1 -0
  48. templates/single-course/content-item.php +7 -11
assets/css/admin/admin.css CHANGED
@@ -2226,6 +2226,17 @@
2226
  display: block;
2227
  border-color: #bdf4fe !important; }
2228
 
 
 
 
 
 
 
 
 
 
 
 
2229
  .section-item-counts {
2230
  position: absolute;
2231
  top: 0;
2226
  display: block;
2227
  border-color: #bdf4fe !important; }
2228
 
2229
+ .wp-admin.post-type-lp_course #meta-box-tab-course_payment .learn-press-tip-floating {
2230
+ top: 40px;
2231
+ left: 100px;
2232
+ background: #a00;
2233
+ opacity: 0.8; }
2234
+ .wp-admin.post-type-lp_course #meta-box-tab-course_payment .learn-press-tip-floating::before {
2235
+ top: -7px;
2236
+ border: 7px solid transparent;
2237
+ border-bottom-color: #a00;
2238
+ border-top-width: 0; }
2239
+
2240
  .section-item-counts {
2241
  position: absolute;
2242
  top: 0;
assets/js/admin/course-editor.js CHANGED
@@ -857,7 +857,6 @@ jQuery(function ($) {
857
  */
858
  (function ($, Vue, $store) {
859
  $(document).ready(function () {
860
- console.log($('#admin-editor-lp_course'))
861
  window.LP_Course_Editor = new Vue({
862
  el: '#admin-editor-lp_course',
863
  template: '<lp-course-editor></lp-course-editor>'
857
  */
858
  (function ($, Vue, $store) {
859
  $(document).ready(function () {
 
860
  window.LP_Course_Editor = new Vue({
861
  el: '#admin-editor-lp_course',
862
  template: '<lp-course-editor></lp-course-editor>'
assets/js/global.js CHANGED
@@ -296,7 +296,7 @@ if (typeof window.LP === 'undefined') {
296
  quickConfirm: function (elem, args) {
297
  var $e = $(elem);
298
  $('[learn-press-quick-confirm]').each(function () {
299
- ( $ins = $(this).data('quick-confirm') ) && ( console.log($ins), $ins.destroy() );
300
  });
301
  !$e.attr('learn-press-quick-confirm') && $e.attr('learn-press-quick-confirm', 'true').data('quick-confirm',
302
  new (function (elem, args) {
@@ -355,7 +355,7 @@ if (typeof window.LP === 'undefined') {
355
  });
356
  //$div.parent().css('position', 'relative');
357
  $div.css({
358
- left: ( ( offset.left + $elem.outerWidth() ) - $div.outerWidth() ) + args.offset.left,
359
  top: offset.top + $elem.outerHeight() + args.offset.top + 5
360
  }).hide().fadeIn('fast');
361
  start();
@@ -415,7 +415,7 @@ if (typeof window.LP === 'undefined') {
415
  },
416
  blockUI: function (message) {
417
 
418
- message = (message !== false ? ( message ? message : 'Wait a moment' ) : '') + '<div class="message-box-animation"></div>';
419
  this.show(message);
420
  },
421
  hide: function (delay, instance) {
@@ -462,7 +462,7 @@ if (typeof window.LP === 'undefined') {
462
  $content.css("height", "").css('overflow', '');
463
  }
464
  $wrap.css({
465
- marginTop: ( $(window).height() - height ) / 2
466
  });
467
  LP.Hook.doAction('learn_press_message_box_resize', height, that);
468
  };
@@ -520,7 +520,7 @@ if (typeof window.LP === 'undefined') {
520
  },
521
  _createButton: function (title, type) {
522
  var $button = $('<button type="button" class="button message-box-button message-box-button-' + type + '">' + title + '</button>'),
523
- callback = 'on' + ( type.substr(0, 1).toUpperCase() + type.substr(1) );
524
  $button.data('callback', callback).click(function () {
525
  var instance = $(this).data('instance'),
526
  callback = instance.events[$(this).data('callback')];
@@ -684,7 +684,7 @@ if (typeof window.LP === 'undefined') {
684
  dataType = args.dataType || 'json',
685
  data = args.action ? $.extend(args.data, {'lp-ajax': args.action}) : args.data,
686
  beforeSend = args.beforeSend || function () {
687
- },
688
  url = args.url || window.location.href;
689
  // console.debug( beforeSend );
690
  $.ajax({
@@ -705,12 +705,12 @@ if (typeof window.LP === 'undefined') {
705
  doAjax: function (args) {
706
  var type = args.type || 'post',
707
  dataType = args.dataType || 'json',
708
- action = ( ( args.prefix === undefined ) || 'learnpress_') + args.action,
709
  data = args.action ? $.extend(args.data, {action: action}) : args.data;
710
 
711
  $.ajax({
712
  data: data,
713
- url: ( args.url || window.location.href ),
714
  type: type,
715
  dataType: 'html',
716
  success: function (raw) {
@@ -815,7 +815,7 @@ if (typeof window.LP === 'undefined') {
815
  }
816
  if (reqWidth > seed.length) { // so short we pad
817
  return new Array(1 + (reqWidth - seed.length))
818
- .join('0') + seed;
819
  }
820
  return seed;
821
  };
@@ -832,7 +832,7 @@ if (typeof window.LP === 'undefined') {
832
 
833
  retId = prefix; // start with prefix, add current milliseconds hex string
834
  retId += formatSeed(parseInt(new Date()
835
- .getTime() / 1000, 10), 8);
836
  retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
837
  if (more_entropy) {
838
  // for more entropy we add a float lower to 10
@@ -1204,6 +1204,8 @@ if (typeof window.LP === 'undefined') {
1204
  if (typeof $.alerts !== 'undefined') {
1205
  $.alerts.overlayColor = '#000';
1206
  $.alerts.overlayOpacity = 0.5;
 
 
1207
  }
1208
 
1209
  $('.learn-press-message.fixed').each(function () {
@@ -1218,12 +1220,64 @@ if (typeof window.LP === 'undefined') {
1218
  if (options.delayOut) {
1219
  setTimeout(function () {
1220
  $el.fadeOut();
1221
- }, options.delayOut + ( options.delayIn || 0));
1222
  }
1223
  })($el, options);
1224
 
1225
  });
1226
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1227
  $('body')
1228
  .on('click', '.learn-press-nav-tabs li a', function (e) {
1229
  e.preventDefault();
296
  quickConfirm: function (elem, args) {
297
  var $e = $(elem);
298
  $('[learn-press-quick-confirm]').each(function () {
299
+ ($ins = $(this).data('quick-confirm')) && (console.log($ins), $ins.destroy());
300
  });
301
  !$e.attr('learn-press-quick-confirm') && $e.attr('learn-press-quick-confirm', 'true').data('quick-confirm',
302
  new (function (elem, args) {
355
  });
356
  //$div.parent().css('position', 'relative');
357
  $div.css({
358
+ left: ((offset.left + $elem.outerWidth()) - $div.outerWidth()) + args.offset.left,
359
  top: offset.top + $elem.outerHeight() + args.offset.top + 5
360
  }).hide().fadeIn('fast');
361
  start();
415
  },
416
  blockUI: function (message) {
417
 
418
+ message = (message !== false ? (message ? message : 'Wait a moment') : '') + '<div class="message-box-animation"></div>';
419
  this.show(message);
420
  },
421
  hide: function (delay, instance) {
462
  $content.css("height", "").css('overflow', '');
463
  }
464
  $wrap.css({
465
+ marginTop: ($(window).height() - height) / 2
466
  });
467
  LP.Hook.doAction('learn_press_message_box_resize', height, that);
468
  };
520
  },
521
  _createButton: function (title, type) {
522
  var $button = $('<button type="button" class="button message-box-button message-box-button-' + type + '">' + title + '</button>'),
523
+ callback = 'on' + (type.substr(0, 1).toUpperCase() + type.substr(1));
524
  $button.data('callback', callback).click(function () {
525
  var instance = $(this).data('instance'),
526
  callback = instance.events[$(this).data('callback')];
684
  dataType = args.dataType || 'json',
685
  data = args.action ? $.extend(args.data, {'lp-ajax': args.action}) : args.data,
686
  beforeSend = args.beforeSend || function () {
687
+ },
688
  url = args.url || window.location.href;
689
  // console.debug( beforeSend );
690
  $.ajax({
705
  doAjax: function (args) {
706
  var type = args.type || 'post',
707
  dataType = args.dataType || 'json',
708
+ action = ((args.prefix === undefined) || 'learnpress_') + args.action,
709
  data = args.action ? $.extend(args.data, {action: action}) : args.data;
710
 
711
  $.ajax({
712
  data: data,
713
+ url: (args.url || window.location.href),
714
  type: type,
715
  dataType: 'html',
716
  success: function (raw) {
815
  }
816
  if (reqWidth > seed.length) { // so short we pad
817
  return new Array(1 + (reqWidth - seed.length))
818
+ .join('0') + seed;
819
  }
820
  return seed;
821
  };
832
 
833
  retId = prefix; // start with prefix, add current milliseconds hex string
834
  retId += formatSeed(parseInt(new Date()
835
+ .getTime() / 1000, 10), 8);
836
  retId += formatSeed(this.php_js.uniqidSeed, 5); // add seed hex string
837
  if (more_entropy) {
838
  // for more entropy we add a float lower to 10
1204
  if (typeof $.alerts !== 'undefined') {
1205
  $.alerts.overlayColor = '#000';
1206
  $.alerts.overlayOpacity = 0.5;
1207
+ $.alerts.okButton = lpGlobalSettings.localize.button_ok;
1208
+ $.alerts.cancelButton = lpGlobalSettings.localize.button_cancel;
1209
  }
1210
 
1211
  $('.learn-press-message.fixed').each(function () {
1220
  if (options.delayOut) {
1221
  setTimeout(function () {
1222
  $el.fadeOut();
1223
+ }, options.delayOut + (options.delayIn || 0));
1224
  }
1225
  })($el, options);
1226
 
1227
  });
1228
 
1229
+
1230
+ $(document).on('input', '#meta-box-tab-course_payment', function (e) {
1231
+ var _self = $(this),
1232
+ _price = $('#_lp_price'),
1233
+ _sale_price = $('#_lp_sale_price'),
1234
+ _target = $(e.target).attr('id');
1235
+ _self.find('#field-_lp_price div, #field-_lp_sale_price div').remove('.learn-press-tip-floating');
1236
+ if (parseInt(_sale_price.val()) >= parseInt(_price.val())) {
1237
+ if (_target === '_lp_price') {
1238
+ _price.parent('.rwmb-input').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_price + '</div>');
1239
+ } else if (_target === '_lp_sale_price') {
1240
+ _sale_price.parent('.rwmb-input').append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_price + '</div>');
1241
+ }
1242
+ }
1243
+ });
1244
+
1245
+ $(document).on('change', '#_lp_sale_start', function (e) {
1246
+ var _sale_start_date = $(this),
1247
+ _sale_end_date = $('#_lp_sale_end'),
1248
+ _start_date = Date.parse(_sale_start_date.val()),
1249
+ _end_date = Date.parse(_sale_end_date.val()),
1250
+ _parent_start = _sale_start_date.parent('.rwmb-input'),
1251
+ _parent_end = _sale_end_date.parent('.rwmb-input');
1252
+
1253
+ if (!_start_date) {
1254
+ _parent_start.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_invalid_date + '</div>')
1255
+ }
1256
+
1257
+ $('#field-_lp_sale_start div, #field-_lp_sale_end div').remove('.learn-press-tip-floating');
1258
+ if (_start_date < _end_date) {
1259
+ _parent_start.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_start_date + '</div>')
1260
+ }
1261
+ });
1262
+
1263
+ $(document).on('change', '#_lp_sale_end', function (e) {
1264
+ var _sale_end_date = $(this),
1265
+ _sale_start_date = $('#_lp_sale_start'),
1266
+ _start_date = Date.parse(_sale_start_date.val()),
1267
+ _end_date = Date.parse(_sale_end_date.val()),
1268
+ _parent_start = _sale_start_date.parent('.rwmb-input'),
1269
+ _parent_end = _sale_end_date.parent('.rwmb-input');
1270
+
1271
+ if (!_end_date) {
1272
+ _parent_end.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_invalid_date + '</div>')
1273
+ }
1274
+
1275
+ $('#field-_lp_sale_start div, #field-_lp_sale_end div').remove('.learn-press-tip-floating');
1276
+ if (_start_date < _end_date) {
1277
+ _parent_end.append('<div class="learn-press-tip-floating">' + lpAdminCourseEditorSettings.i18n.notice_sale_end_date + '</div>')
1278
+ }
1279
+ });
1280
+
1281
  $('body')
1282
  .on('click', '.learn-press-nav-tabs li a', function (e) {
1283
  e.preventDefault();
assets/scss/admin/_admin-editor.scss CHANGED
@@ -625,6 +625,24 @@
625
  }
626
  }
627
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
628
  .section-item-counts {
629
  position: absolute;
630
  top: 0;
625
  }
626
  }
627
 
628
+ .wp-admin.post-type-lp_course {
629
+ #meta-box-tab-course_payment {
630
+ .learn-press-tip-floating {
631
+ top: 40px;
632
+ left: 100px;
633
+ background: #a00;
634
+ opacity: 0.8;
635
+ &::before {
636
+ top: -7px;
637
+ border: 7px solid transparent;
638
+ border-bottom-color: #a00;;
639
+ border-top-width: 0;
640
+ }
641
+ }
642
+ }
643
+ }
644
+
645
+
646
  .section-item-counts {
647
  position: absolute;
648
  top: 0;
inc/admin/class-lp-plugin-install-list-table.php CHANGED
@@ -77,7 +77,7 @@ class LP_Plugin_Install_List_Table extends WP_List_Table {
77
  $cache = WP_CONTENT_DIR . '/upgrade/' . md5( serialize( $add_ons ) ) . '.cache';
78
  $timeover = HOUR_IN_SECONDS * 24;
79
  if( file_exists( $cache ) && ( time() - filemtime( $cache ) ) < $timeover ){
80
- $items = maybe_unserialize( file_get_contents( $cache ) );
81
  }else {
82
  $repo_url = 'http://thimpress.com/lprepo/';
83
 
77
  $cache = WP_CONTENT_DIR . '/upgrade/' . md5( serialize( $add_ons ) ) . '.cache';
78
  $timeover = HOUR_IN_SECONDS * 24;
79
  if( file_exists( $cache ) && ( time() - filemtime( $cache ) ) < $timeover ){
80
+ $items = LP_Helper::maybe_unserialize( file_get_contents( $cache ) );
81
  }else {
82
  $repo_url = 'http://thimpress.com/lprepo/';
83
 
inc/admin/lp-admin-actions.php CHANGED
@@ -18,7 +18,7 @@ function _learn_press_set_user_items( $query ) {
18
  if ( current_user_can( 'manage_options' ) || ! current_user_can( LP_TEACHER_ROLE ) || ! is_admin() || ( $pagenow != 'edit.php' ) ) {
19
  return $query;
20
  }
21
- if ( ! in_array( $post_type, apply_filters( 'lear-press/filter-user-access-types', array(
22
  LP_COURSE_CPT,
23
  LP_LESSON_CPT,
24
  LP_QUIZ_CPT,
18
  if ( current_user_can( 'manage_options' ) || ! current_user_can( LP_TEACHER_ROLE ) || ! is_admin() || ( $pagenow != 'edit.php' ) ) {
19
  return $query;
20
  }
21
+ if ( ! in_array( $post_type, apply_filters( 'learn-press/filter-user-access-types', array(
22
  LP_COURSE_CPT,
23
  LP_LESSON_CPT,
24
  LP_QUIZ_CPT,
inc/class-lp-assets.php CHANGED
@@ -40,10 +40,16 @@ class LP_Assets extends LP_Abstract_Assets {
40
  public function _get_script_data() {
41
  return array(
42
  'global' => array(
43
- 'url' => learn_press_get_current_url(),
44
- 'siteurl' => site_url(),
45
- 'ajax' => admin_url( 'admin-ajax.php' ),
46
- 'theme' => get_stylesheet()
 
 
 
 
 
 
47
  ),
48
  'checkout' => array(
49
  'ajaxurl' => site_url(),
40
  public function _get_script_data() {
41
  return array(
42
  'global' => array(
43
+ 'url' => learn_press_get_current_url(),
44
+ 'siteurl' => site_url(),
45
+ 'ajax' => admin_url( 'admin-ajax.php' ),
46
+ 'theme' => get_stylesheet(),
47
+ 'localize' => array(
48
+ 'button_ok' => __( 'OK', 'learnpress' ),
49
+ 'button_cancel' => __( 'Cancel', 'learnpress' ),
50
+ 'button_yes' => __( 'Yes', 'learnpress' ),
51
+ 'button_no' => __( 'No', 'learnpress' )
52
+ )
53
  ),
54
  'checkout' => array(
55
  'ajaxurl' => site_url(),
inc/class-lp-gdpr.php ADDED
@@ -0,0 +1,557 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Class LP_GDPR
5
+ *
6
+ * Personal data export and removal for LearnPress
7
+ *
8
+ * @since 4.9.6
9
+ */
10
+ class LP_GDPR {
11
+
12
+ /**
13
+ * LP_GDPR constructor.
14
+ */
15
+ public function __construct() {
16
+ // Filter to wp privacy personal data exporter
17
+ add_filter(
18
+ 'wp_privacy_personal_data_exporters',
19
+ array( $this, 'register_exporter' ),
20
+ 10
21
+ );
22
+
23
+ add_filter(
24
+ 'wp_privacy_personal_data_erasers',
25
+ array( $this, 'register_data_eraser' )
26
+ );
27
+ }
28
+
29
+ public function register_data_eraser( $erasers ) {
30
+ $erasers['learnpress'] = array(
31
+ 'eraser_friendly_name' => __( 'LearnPress' ),
32
+ 'callback' => array( $this, 'personal_data_eraser' ),
33
+ );
34
+
35
+ return $erasers;
36
+ }
37
+
38
+ /**
39
+ * @param array $exporters
40
+ *
41
+ * @return mixed
42
+ */
43
+ public function register_exporter( $exporters ) {
44
+
45
+ /**
46
+ * Owned courses
47
+ */
48
+ $exporters['learnpress-owned-courses'] = array(
49
+ 'exporter_friendly_name' => __( 'LearnPress Owned Courses', 'learnpress' ),
50
+ 'callback' => array( $this, 'user_owned_courses' ),
51
+ );
52
+
53
+ /**
54
+ * Orders
55
+ */
56
+ $exporters['learnpress-orders'] = array(
57
+ 'exporter_friendly_name' => __( 'LearnPress Orders', 'learnpress' ),
58
+ 'callback' => array( $this, 'user_orders' ),
59
+ );
60
+
61
+ /**
62
+ * Purchased courses
63
+ */
64
+ $exporters['learnpress-purchased-courses'] = array(
65
+ 'exporter_friendly_name' => __( 'LearnPress Purchased Courses', 'learnpress' ),
66
+ 'callback' => array( $this, 'user_purchased_courses' ),
67
+ );
68
+
69
+ /**
70
+ * Profile
71
+ */
72
+ $exporters['learnpress-profile'] = array(
73
+ 'exporter_friendly_name' => __( 'LearnPress User Profile', 'learnpress' ),
74
+ 'callback' => array( $this, 'user_profile' ),
75
+ );
76
+
77
+ return $exporters;
78
+ }
79
+
80
+ public function user_profile( $email_address, $page ) {
81
+ $export_data = array(
82
+ 'data' => array(),
83
+ 'done' => true
84
+ );
85
+
86
+ if ( ! $wp_user = get_user_by( 'email', $email_address ) ) {
87
+ return $export_data;
88
+ }
89
+
90
+ $user = learn_press_get_user( $wp_user->ID );
91
+ $profile = LP_Profile::instance( $wp_user->ID );
92
+ $export_items = array();
93
+
94
+ if ( $user = $profile->get_user() ) {
95
+ if ( $publicity = $user->get_data( 'profile_publicity' ) ) {
96
+ $export_item = array(
97
+ 'group_id' => 'lp-profile',
98
+ 'group_label' => __( 'Profile Settings', 'learnpress' ),
99
+ 'item_id' => "profile-" . $wp_user->ID,
100
+ 'data' => array()
101
+ );
102
+ foreach ( $publicity as $key => $item ) {
103
+ $export_item['data'][] = array(
104
+ 'name' => $key,
105
+ 'value' => $item
106
+ );
107
+ }
108
+ $export_items[] = $export_item;
109
+ }
110
+ }
111
+
112
+ $export_data['data'] = $export_items;
113
+
114
+ return $export_data;
115
+ }
116
+
117
+ public function user_orders( $email_address, $page ) {
118
+ $number = 10; // Limit us to avoid timing out
119
+ $page = (int) $page;
120
+ $export_data = array(
121
+ 'data' => array(),
122
+ 'done' => true
123
+ );
124
+
125
+ if ( ! $wp_user = get_user_by( 'email', $email_address ) ) {
126
+ return $export_data;
127
+ }
128
+
129
+ $profile = LP_Profile::instance( $wp_user->ID );
130
+
131
+ if ( ! $query_orders = $profile->query_orders( array( 'paged' => $page, 'limit' => $number ) ) ) {
132
+ return $export_data;
133
+ }
134
+
135
+ if ( ! $orders = $query_orders->get_items() ) {
136
+ return $export_data;
137
+ }
138
+
139
+ $export_items = array();
140
+ foreach ( $orders as $order ) {
141
+ if ( ! $order instanceof LP_Order ) {
142
+ $order = learn_press_get_order( $order );
143
+ }
144
+
145
+ $data = array(
146
+ array(
147
+ 'name' => __( 'Order ID', 'learnpress' ),
148
+ 'value' => $order->get_order_number()
149
+ ),
150
+ array(
151
+ 'name' => __( 'Order Date', 'learnpress' ),
152
+ 'value' => $order->get_order_date()
153
+ ),
154
+ array(
155
+ 'name' => __( 'Order status', 'learnpress' ),
156
+ 'value' => $order->get_order_status()
157
+ ),
158
+ array(
159
+ 'name' => __( 'Order Total', 'learnpress' ),
160
+ 'value' => $order->get_formatted_order_total()
161
+ )
162
+ );
163
+ $export_items[] = array(
164
+ 'group_id' => 'lp-order',
165
+ 'group_label' => __( 'Orders', 'learnpress' ),
166
+ 'item_id' => "order-{$order->get_id()}",
167
+ 'data' => $data
168
+ );
169
+ }
170
+
171
+ $done = count( $orders ) < $number;
172
+ $export_data['done'] = $done;
173
+ $export_data['data'] = $export_items;
174
+
175
+ return $export_data;
176
+ }
177
+
178
+ /**
179
+ * Course list
180
+ *
181
+ * @param string $email_address
182
+ * @param int $page
183
+ *
184
+ * @return array
185
+ */
186
+ public function user_owned_courses( $email_address, $page ) {
187
+
188
+ $number = 10; // Limit us to avoid timing out
189
+ $page = (int) $page;
190
+ $export_items = array();
191
+
192
+ $query = $this->get_courses_by_email( 'own', $email_address, array(
193
+ 'paged' => $page,
194
+ 'limit' => $number,
195
+ 'status' => '*'
196
+ ) );
197
+
198
+ if ( ! $query ) {
199
+ return array(
200
+ 'data' => array(),
201
+ 'done' => true
202
+ );
203
+ }
204
+
205
+ if ( $courses = (array) $query->get_items() ) {
206
+ foreach ( $courses as $course_id ) {
207
+ if ( ! $course = learn_press_get_course( $course_id ) ) {
208
+ continue;
209
+ }
210
+
211
+ $data = array(
212
+ array(
213
+ 'name' => __( 'Course Author', 'learnpress' ),
214
+ 'value' => $course->get_author_display_name()
215
+ ),
216
+ array(
217
+ 'name' => __( 'Course Name', 'learnpress' ),
218
+ 'value' => $course->get_title()
219
+ ),
220
+ array(
221
+ 'name' => __( 'Course Date', 'learnpress' ),
222
+ 'value' => get_post_field( 'post_date', $course_id )
223
+ ),
224
+ array(
225
+ 'name' => __( 'Course URL', 'learnpress' ),
226
+ 'value' => $course->get_permalink()
227
+ )
228
+ );
229
+ $export_items[] = array(
230
+ 'group_id' => 'lp-owned-course',
231
+ 'group_label' => __( 'Owned Course', 'learnpress' ),
232
+ 'item_id' => "course-{$course->get_id()}",
233
+ 'data' => $data
234
+ );
235
+
236
+ $this->_export_course_items( $export_items, $course_id );
237
+ }
238
+ }
239
+ $done = count( $courses ) < $number;
240
+
241
+ return array(
242
+ 'data' => $export_items,
243
+ 'done' => $done
244
+ );
245
+ }
246
+
247
+ /**
248
+ * @param array $export_items
249
+ */
250
+ protected function _export_course_items( &$export_items, $course_id ) {
251
+ global $post;
252
+ $post = get_post( $course_id );
253
+ setup_postdata( $post );
254
+ $course = learn_press_get_course( $course_id );
255
+
256
+ if ( ! $items = $course->get_items() ) {
257
+ return;
258
+ }
259
+
260
+ foreach ( $items as $item_id ) {
261
+ $item = $course->get_item( $item_id );
262
+ $export_item_data = array(
263
+ array(
264
+ 'name' => __( 'Item Name', 'learnpress' ),
265
+ 'value' => $item->get_title()
266
+ ),
267
+ array(
268
+ 'name' => __( 'Item Type', 'learnpress' ),
269
+ 'value' => $item->get_item_type( 'display' )
270
+ ),
271
+ array(
272
+ 'name' => __( 'Item URL', 'learnpress' ),
273
+ 'value' => $item->get_permalink()
274
+ )
275
+ );
276
+
277
+ $export_items[] = array(
278
+ 'group_id' => 'lp-owned-course-items-' . $course_id,
279
+ 'group_label' => __( 'Course Items', 'learnpress' ),
280
+ 'item_id' => "course-items-{$course_id}-{$item_id}",
281
+ 'data' => $export_item_data
282
+ );
283
+ }
284
+
285
+ wp_reset_postdata();
286
+ }
287
+
288
+ /**
289
+ * @param string $email_address
290
+ * @param string $page
291
+ *
292
+ * @return array
293
+ */
294
+ public function user_purchased_courses( $email_address, $page ) {
295
+
296
+ $number = 10; // Limit us to avoid timing out
297
+ $page = (int) $page;
298
+ $export_data = array(
299
+ 'data' => array(),
300
+ 'done' => true
301
+ );
302
+ if ( ! $wp_user = get_user_by( 'email', $email_address ) ) {
303
+ return $export_data;
304
+ }
305
+
306
+ $user = learn_press_get_user( $wp_user->ID );
307
+ $query = $this->get_courses_by_email( 'purchased', $email_address, array(
308
+ 'paged' => $page,
309
+ 'limit' => $number
310
+ ) );
311
+
312
+
313
+ if ( ! $query ) {
314
+ return $export_data;
315
+ }
316
+
317
+ $export_items = array();
318
+ if ( $courses = (array) $query->get_items() ) {
319
+
320
+ foreach ( $courses as $course_data ) {
321
+
322
+ $course = learn_press_get_course( $course_data->get_id() );
323
+ //if ( $course_data = $user->get_course_data( $course_id ) ) {
324
+ $enrolled_date = $course_data->get_start_time();
325
+ $finished_date = $course_data->get_end_time();
326
+ $status = $course_data->get_status();
327
+ $grade = $course_data->get_grade();
328
+ //}
329
+
330
+ $data = array(
331
+ array(
332
+ 'name' => __( 'Course Author', 'learnpress' ),
333
+ 'value' => $course->get_author_display_name()
334
+ ),
335
+ array(
336
+ 'name' => __( 'Course Name', 'learnpress' ),
337
+ 'value' => $course->get_title()
338
+ ),
339
+ array(
340
+ 'name' => __( 'Course Date', 'learnpress' ),
341
+ 'value' => get_post_field( 'post_date', $course_data->get_id() )
342
+ ),
343
+ array(
344
+ 'name' => __( 'Course URL', 'learnpress' ),
345
+ 'value' => $course->get_permalink()
346
+ ),
347
+ array(
348
+ 'name' => __( 'Enrolled Date', 'learnpress' ),
349
+ 'value' => $enrolled_date
350
+ ),
351
+ array(
352
+ 'name' => __( 'Finished Date', 'learnpress' ),
353
+ 'value' => $finished_date ? $finished_date : '-'
354
+ ),
355
+ array(
356
+ 'name' => __( 'Course Status', 'learnpress' ),
357
+ 'value' => $status
358
+ ),
359
+ array(
360
+ 'name' => __( 'Course Grade', 'learnpress' ),
361
+ 'value' => $status == 'finished' ? $grade : __( 'Ungraded', 'learnpress' )
362
+ )
363
+ );
364
+ $export_items[] = array(
365
+ 'group_id' => 'lp-purchased-course-' . $course_data->get_id(),
366
+ 'group_label' => __( 'Purchased Course', 'learnpress' ),
367
+ 'item_id' => "course-{$course_data->get_id()}",
368
+ 'data' => $data
369
+ );
370
+
371
+ $this->_export_purchased_course_items( $export_items, $course_data );
372
+ }
373
+ }
374
+
375
+ $done = count( $courses ) < $number;
376
+ $export_data['data'] = $export_items;
377
+ $export_data['done'] = $done;
378
+
379
+ return $export_data;
380
+ }
381
+
382
+ /**
383
+ * @param array $export_items
384
+ * @param LP_User_Item_Course $course_data
385
+ */
386
+ protected function _export_purchased_course_items( &$export_items, $course_data ) {
387
+ global $post;
388
+ $post = get_post( $course_data->get_id() );
389
+ setup_postdata( $post );
390
+ $course = learn_press_get_course( $course_data->get_id() );
391
+
392
+ if ( ! $items = $course_data->get_items() ) {
393
+ return;
394
+ }
395
+
396
+ foreach ( $items as $user_course_item ) {
397
+ $item = $course->get_item( $user_course_item->get_id() );
398
+ $export_item_data = array(
399
+ array(
400
+ 'name' => __( 'Item Name', 'learnpress' ),
401
+ 'value' => $item->get_title()
402
+ ),
403
+ array(
404
+ 'name' => __( 'Item Type', 'learnpress' ),
405
+ 'value' => $item->get_item_type( 'display' )
406
+ ),
407
+ array(
408
+ 'name' => __( 'Item URL', 'learnpress' ),
409
+ 'value' => $item->get_permalink()
410
+ )
411
+ );
412
+
413
+ if ( $item->get_item_type() == LP_QUIZ_CPT ) {
414
+ $export_item_data[] = array(
415
+ 'name' => __( 'Status', 'learnpress' ),
416
+ 'value' => $user_course_item->get_result() . '%'
417
+ );
418
+
419
+ $export_item_data[] = array(
420
+ 'name' => __( 'Grade', 'learnpress' ),
421
+ 'value' => $user_course_item->get_result( 'grade' )
422
+ );
423
+ } elseif ( $item->get_item_type() == LP_LESSON_CPT ) {
424
+ $export_item_data[] = array(
425
+ 'name' => __( 'Completed', 'learnpress' ),
426
+ 'value' => $user_course_item->get_status() === 'completed' ? __( 'Yes', 'learnpress' ) : __( 'No', 'learnpress' )
427
+ );
428
+ }
429
+
430
+ $export_items[] = array(
431
+ 'group_id' => 'lp-purchased-course-items-' . $course_data->get_id(),
432
+ 'group_label' => __( 'Course Items', 'learnpress' ),
433
+ 'item_id' => "course-{$course_data->get_id()}-{$user_course_item->get_id()}",
434
+ 'data' => $export_item_data
435
+ );
436
+ }
437
+
438
+ wp_reset_postdata();
439
+ }
440
+
441
+ /**
442
+ * Query all courses by user email
443
+ *
444
+ * @param string $type
445
+ * @param string $email
446
+ * @param array $args
447
+ *
448
+ * @return array|bool|LP_Query_List_Table
449
+ */
450
+ protected function get_courses_by_email( $type = 'own', $email, $args = array() ) {
451
+ if ( ! $user = get_user_by( 'email', $email ) ) {
452
+ return false;
453
+ }
454
+
455
+ $profile = LP_Profile::instance( $user->ID );
456
+
457
+ return $profile->query_courses(
458
+ $type,
459
+ $args
460
+ );
461
+ }
462
+
463
+ /**
464
+ * Eraser personal data
465
+ *
466
+ * @param string $email
467
+ * @param int $page
468
+ *
469
+ * @return array
470
+ */
471
+ public function personal_data_eraser( $email, $page ) {
472
+ $number = 500;
473
+ $page = (int) $page;
474
+
475
+ $eraser_data = array(
476
+ 'items_removed' => false,
477
+ 'items_retained' => false,
478
+ 'messages' => array(),
479
+ 'done' => 1,
480
+ );
481
+
482
+ if ( ! $wp_user = get_user_by( 'email', $email ) ) {
483
+ return $eraser_data;
484
+ }
485
+
486
+ $this->_eraser_orders( $wp_user->ID, $page );
487
+ $this->_eraser_user_items( $wp_user->ID, $page );
488
+ $this->_eraser_courses( $wp_user->ID, $page );
489
+
490
+ delete_user_meta( $wp_user->ID, '_lp_profile_publicity' );
491
+ $eraser_data['items_removed'] = true;
492
+
493
+ return $eraser_data;
494
+ }
495
+
496
+ /**
497
+ * Eraser orders
498
+ *
499
+ * @param int $user_id
500
+ * @param int $page
501
+ */
502
+ protected function _eraser_orders( $user_id, $page ) {
503
+
504
+ $curd = new LP_User_CURD();
505
+ $order_curd = new LP_Order_CURD();
506
+
507
+ if ( ! $orders = $curd->get_orders( $user_id, array( 'group_by_order' => true ) ) ) {
508
+ return;
509
+ }
510
+
511
+ foreach ( $orders as $order_id => $course_ids ) {
512
+ $order = learn_press_get_order( $order_id );
513
+ //$order_curd->delete_order_data( $order );
514
+ wp_delete_post( $order_id );
515
+ }
516
+
517
+ }
518
+
519
+ /**
520
+ * Eraser user items
521
+ *
522
+ * @param int $user_id
523
+ * @param int $page
524
+ */
525
+ protected function _eraser_user_items( $user_id, $page ) {
526
+ $curd = new LP_User_CURD();
527
+ $curd->delete_user_item( array( 'user_id' => $user_id ) );
528
+ }
529
+
530
+ /**
531
+ * Eraser courses
532
+ *
533
+ * @param int $user_id
534
+ * @param int $page
535
+ */
536
+ protected function _eraser_courses( $user_id, $page ) {
537
+
538
+ global $wpdb;
539
+ $query = $wpdb->prepare( "
540
+ SELECT *
541
+ FROM {$wpdb->posts}
542
+ WHERE post_author = %d
543
+ AND post_type = %s
544
+ ", $user_id, LP_COURSE_CPT );
545
+ if ( ! $post_ids = $wpdb->get_col( $query ) ) {
546
+ return;
547
+ }
548
+
549
+ $api = new LP_Course_CURD();
550
+ foreach ( $post_ids as $post_id ) {
551
+ $api->delete_course( $post_id, true );
552
+ }
553
+ }
554
+
555
+ }
556
+
557
+ return new LP_GDPR();
inc/class-lp-hard-cache.php CHANGED
@@ -132,7 +132,7 @@ class LP_Hard_Cache {
132
  return false;
133
  }
134
 
135
- return maybe_unserialize( $content );
136
  }
137
 
138
  return false;
132
  return false;
133
  }
134
 
135
+ return LP_Helper::maybe_unserialize( $content );
136
  }
137
 
138
  return false;
inc/class-lp-helper.php CHANGED
@@ -6,6 +6,41 @@
6
  defined( 'ABSPATH' ) || exit;
7
 
8
  class LP_Helper {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  /**
10
  * Shuffle array and keep the keys
11
  *
6
  defined( 'ABSPATH' ) || exit;
7
 
8
  class LP_Helper {
9
+
10
+ /**
11
+ * Wrap function unserialize to fix issues with UTF-8 chars when encoding/decoding
12
+ * of serialize function.
13
+ *
14
+ * @param string $string
15
+ *
16
+ * @return mixed
17
+ */
18
+ public static function maybe_unserialize( $string ) {
19
+ if ( is_string( $string ) ) {
20
+
21
+ $unserialized = maybe_unserialize( $string );
22
+ if ( ! $unserialized && strlen( $string ) ) {
23
+ $string = preg_replace_callback(
24
+ '!s:(\d+):"(.*?)";!s',
25
+ array( __CLASS__, '_unserialize_replace_callback' ),
26
+ $string );
27
+
28
+ $unserialized = maybe_unserialize( $string );
29
+ }
30
+
31
+ $string = $unserialized;
32
+ }
33
+
34
+ return $string;
35
+ }
36
+
37
+ public static function _unserialize_replace_callback( $m ) {
38
+ $len = strlen( $m[2] );
39
+ $result = "s:$len:\"{$m[2]}\";";
40
+
41
+ return $result;
42
+ }
43
+
44
  /**
45
  * Shuffle array and keep the keys
46
  *
inc/class-lp-install.php CHANGED
@@ -246,7 +246,7 @@ if ( ! function_exists( 'LP_Install' ) ) {
246
  parse_str( $str, $options );
247
  if ( $options ) {
248
  foreach ( $options as $name => $value ) {
249
- $value = maybe_unserialize( $value );
250
  update_option( $name, $value, 'yes' );
251
  }
252
  }
246
  parse_str( $str, $options );
247
  if ( $options ) {
248
  foreach ( $options as $name => $value ) {
249
+ $value = LP_Helper::maybe_unserialize( $value );
250
  update_option( $name, $value, 'yes' );
251
  }
252
  }
inc/class-lp-session-handler.php CHANGED
@@ -284,7 +284,7 @@ class LP_Session_Handler implements ArrayAccess {
284
  wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
285
  }
286
 
287
- return maybe_unserialize( $value );
288
  }
289
 
290
  public function delete_session( $customer_id ) {
@@ -344,7 +344,7 @@ class LP_Session_Handler implements ArrayAccess {
344
  public function get( $key, $default = null ) {
345
  $key = sanitize_key( $key );
346
 
347
- return isset( $this->_data[ $key ] ) ? maybe_unserialize( $this->_data[ $key ] ) : $default;
348
  }
349
 
350
  /**
284
  wp_cache_add( $this->get_cache_prefix() . $customer_id, $value, LP_SESSION_CACHE_GROUP, $this->_session_expiration - time() );
285
  }
286
 
287
+ return LP_Helper::maybe_unserialize( $value );
288
  }
289
 
290
  public function delete_session( $customer_id ) {
344
  public function get( $key, $default = null ) {
345
  $key = sanitize_key( $key );
346
 
347
+ return isset( $this->_data[ $key ] ) ? LP_Helper::maybe_unserialize( $this->_data[ $key ] ) : $default;
348
  }
349
 
350
  /**
inc/class-lp-settings.php CHANGED
@@ -91,7 +91,7 @@ class LP_Settings {
91
 
92
  if ( $options = $wpdb->get_results( $query ) ) {
93
  foreach ( $options as $option ) {
94
- $this->_options[ $option->option_name ] = maybe_unserialize( $option->option_value );
95
  }
96
  }
97
  }
@@ -114,7 +114,7 @@ class LP_Settings {
114
  $current_var = array_shift( $var );
115
  if ( is_object( $obj ) ) {
116
  if ( isset( $obj->{$current_var} ) ) {
117
- $obj->{$current_var} = maybe_unserialize( $obj->{$current_var} );
118
  if ( count( $var ) ) {
119
  $this->_set_option( $obj->{$current_var}, join( '.', $var ), $value );
120
  } else {
@@ -125,7 +125,7 @@ class LP_Settings {
125
  }
126
  } else {
127
  if ( isset( $obj[ $current_var ] ) ) {
128
- $obj[ $current_var ] = maybe_unserialize( $obj[ $current_var ] );
129
  if ( count( $var ) ) {
130
  $this->_set_option( $obj[ $current_var ], join( '.', $var ), $value );
131
  } else {
@@ -174,7 +174,7 @@ class LP_Settings {
174
  $current_var = array_shift( $var );
175
  if ( is_object( $obj ) ) {
176
  if ( isset( $obj->{$current_var} ) ) {
177
- $obj->{$current_var} = maybe_unserialize( $obj->{$current_var} );
178
  if ( count( $var ) ) {
179
  return $this->_get_option( $obj->{$current_var}, join( '.', $var ), $default );
180
  } else {
@@ -185,7 +185,7 @@ class LP_Settings {
185
  }
186
  } else {
187
  if ( isset( $obj[ $current_var ] ) ) {
188
- $obj[ $current_var ] = maybe_unserialize( $obj[ $current_var ] );
189
  if ( count( $var ) ) {
190
  return $this->_get_option( $obj[ $current_var ], join( '.', $var ), $default );
191
  } else {
@@ -318,7 +318,7 @@ class LP_Settings {
318
 
319
  foreach ( $options as $o_name ) {
320
  if ( ! empty( $alloptions_db[ $o_name ] ) ) {
321
- $o_value = maybe_unserialize( $alloptions_db[ $o_name ]->option_value );
322
  wp_cache_set( $o_name, $o_value, 'options' );
323
  } else {
324
  if ( ! is_array( $notoptions ) ) {
91
 
92
  if ( $options = $wpdb->get_results( $query ) ) {
93
  foreach ( $options as $option ) {
94
+ $this->_options[ $option->option_name ] = LP_Helper::maybe_unserialize( $option->option_value );
95
  }
96
  }
97
  }
114
  $current_var = array_shift( $var );
115
  if ( is_object( $obj ) ) {
116
  if ( isset( $obj->{$current_var} ) ) {
117
+ $obj->{$current_var} = LP_Helper::maybe_unserialize( $obj->{$current_var} );
118
  if ( count( $var ) ) {
119
  $this->_set_option( $obj->{$current_var}, join( '.', $var ), $value );
120
  } else {
125
  }
126
  } else {
127
  if ( isset( $obj[ $current_var ] ) ) {
128
+ $obj[ $current_var ] = LP_Helper::maybe_unserialize( $obj[ $current_var ] );
129
  if ( count( $var ) ) {
130
  $this->_set_option( $obj[ $current_var ], join( '.', $var ), $value );
131
  } else {
174
  $current_var = array_shift( $var );
175
  if ( is_object( $obj ) ) {
176
  if ( isset( $obj->{$current_var} ) ) {
177
+ $obj->{$current_var} = LP_Helper::maybe_unserialize( $obj->{$current_var} );
178
  if ( count( $var ) ) {
179
  return $this->_get_option( $obj->{$current_var}, join( '.', $var ), $default );
180
  } else {
185
  }
186
  } else {
187
  if ( isset( $obj[ $current_var ] ) ) {
188
+ $obj[ $current_var ] = LP_Helper::maybe_unserialize( $obj[ $current_var ] );
189
  if ( count( $var ) ) {
190
  return $this->_get_option( $obj[ $current_var ], join( '.', $var ), $default );
191
  } else {
318
 
319
  foreach ( $options as $o_name ) {
320
  if ( ! empty( $alloptions_db[ $o_name ] ) ) {
321
+ $o_value = LP_Helper::maybe_unserialize( $alloptions_db[ $o_name ]->option_value );
322
  wp_cache_set( $o_name, $o_value, 'options' );
323
  } else {
324
  if ( ! is_array( $notoptions ) ) {
inc/course/abstract-course.php CHANGED
@@ -1819,6 +1819,23 @@ if ( ! function_exists( 'LP_Abstract_Course' ) ) {
1819
  return learn_press_get_user( get_post_field( 'post_author', $this->get_id() ) );
1820
  }
1821
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1822
  /**
1823
  * @return mixed
1824
  */
1819
  return learn_press_get_user( get_post_field( 'post_author', $this->get_id() ) );
1820
  }
1821
 
1822
+ /**
1823
+ * Get author's display name
1824
+ *
1825
+ * @since 3.0.9
1826
+ *
1827
+ * @return string
1828
+ */
1829
+ public function get_author_display_name() {
1830
+ $display_name = '';
1831
+
1832
+ if ( $user = $this->get_author() ) {
1833
+ $display_name = $user->get_display_name();
1834
+ }
1835
+
1836
+ return $display_name;
1837
+ }
1838
+
1839
  /**
1840
  * @return mixed
1841
  */
inc/course/class-lp-course-item.php CHANGED
@@ -64,10 +64,22 @@ if ( ! class_exists( 'LP_Course_Item' ) ) {
64
  }
65
 
66
  /**
 
 
 
 
67
  * @return string
68
  */
69
- public function get_item_type() {
70
- return $this->_item_type;
 
 
 
 
 
 
 
 
71
  }
72
 
73
  /**
@@ -514,6 +526,14 @@ if ( ! class_exists( 'LP_Course_Item' ) ) {
514
  $course_id = get_the_ID();
515
  }
516
 
 
 
 
 
 
 
 
 
517
  $key = 'course-item-' . $user_id . '-' . $course_id;
518
 
519
  if ( false === ( $blocked_items = wp_cache_get( $key, 'blocked-items' ) ) ) {
64
  }
65
 
66
  /**
67
+ * Get type of item.
68
+ *
69
+ * @param string $context
70
+ *
71
  * @return string
72
  */
73
+ public function get_item_type( $context = '' ) {
74
+ $post_type = $this->_item_type;
75
+
76
+ if ( $context === 'display' ) {
77
+ if ( $post_type_object = get_post_type_object( $post_type ) ) {
78
+ $post_type = $post_type_object->labels->singular_name;
79
+ }
80
+ }
81
+
82
+ return $post_type;
83
  }
84
 
85
  /**
526
  $course_id = get_the_ID();
527
  }
528
 
529
+ $course_author = learn_press_get_course_user( $course_id );
530
+ if ( $course_author ) {
531
+ $author_id = $course_author->get_id();
532
+ if ( $author_id == $user_id ) {
533
+ return false;
534
+ }
535
+ }
536
+
537
  $key = 'course-item-' . $user_id . '-' . $course_id;
538
 
539
  if ( false === ( $blocked_items = wp_cache_get( $key, 'blocked-items' ) ) ) {
inc/course/lp-course-functions.php CHANGED
@@ -710,7 +710,7 @@ if ( ! function_exists( 'learn_press_get_nav_course_item_url' ) ) {
710
  function learn_press_get_nav_course_item_url( $course_id = null, $item_id = null, $content_only = false ) {
711
 
712
  $course = learn_press_get_course( $course_id );
713
- $curriculum_items = $course->get_items();// maybe_unserialize( $course->post->curriculum_items );
714
  $index = array_search( $item_id, $curriculum_items );
715
  $return = array( 'back' => '', 'next' => '' );
716
  if ( is_array( $curriculum_items ) ) {
710
  function learn_press_get_nav_course_item_url( $course_id = null, $item_id = null, $content_only = false ) {
711
 
712
  $course = learn_press_get_course( $course_id );
713
+ $curriculum_items = $course->get_items();// LP_Helper::maybe_unserialize( $course->post->curriculum_items );
714
  $index = array_search( $item_id, $curriculum_items );
715
  $return = array( 'back' => '', 'next' => '' );
716
  if ( is_array( $curriculum_items ) ) {
inc/curds/class-lp-course-curd.php CHANGED
@@ -89,6 +89,26 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
89
  $curd->clear();
90
  }
91
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
92
  /**
93
  * Duplicate course.
94
  *
89
  $curd->clear();
90
  }
91
 
92
+ /**
93
+ * Delete course itself and sections.
94
+ *
95
+ * @param int|object $course_id
96
+ * @param bool $delete_item - Optional. TRUE will delete all items assigned to course
97
+ */
98
+ public function delete_course( $course_id, $delete_item = false ) {
99
+ if ( $delete_item ) {
100
+ if($course = learn_press_get_course( $course_id )) {
101
+ if ( $items = $course->get_items() ) {
102
+ foreach ( $items as $item ) {
103
+ wp_delete_post( $item );
104
+ }
105
+ }
106
+ }
107
+ }
108
+
109
+ wp_delete_post( $course_id );
110
+ }
111
+
112
  /**
113
  * Duplicate course.
114
  *
inc/curds/class-lp-order-curd.php CHANGED
@@ -131,7 +131,7 @@ class LP_Order_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
131
  public function get_item_meta( &$item ) {
132
  if ( $metas = get_metadata( 'learnpress_order_item', $item['id'] ) ) {
133
  foreach ( $metas as $k => $v ) {
134
- $item[ preg_replace( '!^_!', '', $k ) ] = maybe_unserialize( $v[0] );
135
  }
136
  };
137
  //$item = wp_parse_args()
131
  public function get_item_meta( &$item ) {
132
  if ( $metas = get_metadata( 'learnpress_order_item', $item['id'] ) ) {
133
  foreach ( $metas as $k => $v ) {
134
+ $item[ preg_replace( '!^_!', '', $k ) ] = LP_Helper::maybe_unserialize( $v[0] );
135
  }
136
  };
137
  //$item = wp_parse_args()
inc/curds/class-lp-question-curd.php CHANGED
@@ -870,7 +870,7 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
870
  if ( $answer_options = $wpdb->get_results( $query, OBJECT_K ) ) {
871
  foreach ( $answer_options as $k => $v ) {
872
  $answer_options[ $k ] = (array) $answer_options[ $k ];
873
- if ( $answer_data = maybe_unserialize( $v->answer_data ) ) {
874
  foreach ( $answer_data as $data_key => $data_value ) {
875
  $answer_options[ $k ][ $data_key ] = $data_value;
876
  }
@@ -932,7 +932,7 @@ if ( ! class_exists( 'LP_Question_CURD' ) ) {
932
  $question_answers[ $qid ] = array();
933
  }
934
 
935
- if ( $answer_data = maybe_unserialize( $v->answer_data ) ) {
936
  foreach ( $answer_data as $data_key => $data_value ) {
937
  $v->{$data_key} = $data_value;
938
  }
870
  if ( $answer_options = $wpdb->get_results( $query, OBJECT_K ) ) {
871
  foreach ( $answer_options as $k => $v ) {
872
  $answer_options[ $k ] = (array) $answer_options[ $k ];
873
+ if ( $answer_data = LP_Helper::maybe_unserialize( $v->answer_data ) ) {
874
  foreach ( $answer_data as $data_key => $data_value ) {
875
  $answer_options[ $k ][ $data_key ] = $data_value;
876
  }
932
  $question_answers[ $qid ] = array();
933
  }
934
 
935
+ if ( $answer_data = LP_Helper::maybe_unserialize( $v->answer_data ) ) {
936
  foreach ( $answer_data as $data_key => $data_value ) {
937
  $v->{$data_key} = $data_value;
938
  }
inc/curds/class-lp-user-curd.php CHANGED
@@ -120,7 +120,6 @@ class LP_User_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
120
  * )
121
  *
122
  * @param int $user_id
123
- * @param bool $group_by_order - Optional. Group by order id instead of by course id
124
  * @param array $args
125
  *
126
  * @return array|mixed
@@ -529,7 +528,7 @@ class LP_User_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
529
  if ( $meta = $wpdb->get_results( $query, ARRAY_A ) ) {
530
  $item['meta'] = array();
531
  foreach ( $meta as $k => $v ) {
532
- $v['meta_value'] = maybe_unserialize( $v['meta_value'] );
533
  $item['meta'][ $v['meta_id'] ] = $v;
534
  }
535
  }
@@ -939,10 +938,7 @@ class LP_User_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
939
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->learnpress_user_itemmeta} WHERE learnpress_user_item_id = %d", $user_item_id ) );
940
  do_action( 'learn-press/deleted-user-item', $user_item_id );
941
  }
942
- // if($user_item_ids) {
943
- // // Flush all cache to apply new changes
944
- // wp_cache_flush();
945
- // }
946
 
947
  return true;
948
  }
@@ -1046,7 +1042,7 @@ class LP_User_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
1046
  } else {
1047
  if ( 'pending' === $args['status'] ) {
1048
  $where .= $wpdb->prepare( " AND post_status IN( %s, %s )", array( 'draft', 'pending' ) );
1049
- } else {
1050
  $where .= $wpdb->prepare( " AND post_status = %s", $args['status'] );
1051
  }
1052
  }
@@ -1564,4 +1560,6 @@ class LP_User_CURD extends LP_Object_Data_CURD implements LP_Interface_CURD {
1564
 
1565
  return $new_user;
1566
  }
 
 
1567
  }
120
  * )
121
  *
122
  * @param int $user_id
 
123
  * @param array $args
124
  *
125
  * @return array|mixed
528
  if ( $meta = $wpdb->get_results( $query, ARRAY_A ) ) {
529
  $item['meta'] = array();
530
  foreach ( $meta as $k => $v ) {
531
+ $v['meta_value'] = LP_Helper::maybe_unserialize( $v['meta_value'] );
532
  $item['meta'][ $v['meta_id'] ] = $v;
533
  }
534
  }
938
  $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->learnpress_user_itemmeta} WHERE learnpress_user_item_id = %d", $user_item_id ) );
939
  do_action( 'learn-press/deleted-user-item', $user_item_id );
940
  }
941
+
 
 
 
942
 
943
  return true;
944
  }
1042
  } else {
1043
  if ( 'pending' === $args['status'] ) {
1044
  $where .= $wpdb->prepare( " AND post_status IN( %s, %s )", array( 'draft', 'pending' ) );
1045
+ } elseif ( $args['status'] !== '*' ) {
1046
  $where .= $wpdb->prepare( " AND post_status = %s", $args['status'] );
1047
  }
1048
  }
1560
 
1561
  return $new_user;
1562
  }
1563
+
1564
+
1565
  }
inc/curds/class-lp-user-item-curd.php CHANGED
@@ -143,7 +143,7 @@ class LP_User_Item_CURD implements LP_Interface_CURD {
143
  $answer_options[ $v->question_id ] = array();
144
  }
145
  $v = (array) $v;
146
- if ( $answer_data = maybe_unserialize( $v['answer_data'] ) ) {
147
  foreach ( $answer_data as $kk => $vv ) {
148
  $v[ $kk ] = $vv;
149
  }
@@ -154,7 +154,7 @@ class LP_User_Item_CURD implements LP_Interface_CURD {
154
  $answer_options[ $v['question_id'] ][] = $v;
155
  /*$kk = sizeof( $answer_options[ $v->question_id ] );
156
 
157
- if ( $answer_data = maybe_unserialize( $v->answer_data ) ) {
158
  foreach ( $answer_data as $data_key => $data_value ) {
159
  $answer_options[ $v->question_id ][ $kk ][ $data_key ] = $data_value;
160
  }
@@ -414,6 +414,9 @@ class LP_User_Item_CURD implements LP_Interface_CURD {
414
  return learn_press_update_user_item_meta( $object->get_user_item_id(), $meta->meta_key, $meta->meta_value );
415
  }
416
 
 
 
 
417
  /**
418
  * Get WP_Object.
419
  *
143
  $answer_options[ $v->question_id ] = array();
144
  }
145
  $v = (array) $v;
146
+ if ( $answer_data = LP_Helper::maybe_unserialize( $v['answer_data'] ) ) {
147
  foreach ( $answer_data as $kk => $vv ) {
148
  $v[ $kk ] = $vv;
149
  }
154
  $answer_options[ $v['question_id'] ][] = $v;
155
  /*$kk = sizeof( $answer_options[ $v->question_id ] );
156
 
157
+ if ( $answer_data = LP_Helper::maybe_unserialize( $v->answer_data ) ) {
158
  foreach ( $answer_data as $data_key => $data_value ) {
159
  $answer_options[ $v->question_id ][ $kk ][ $data_key ] = $data_value;
160
  }
414
  return learn_press_update_user_item_meta( $object->get_user_item_id(), $meta->meta_key, $meta->meta_value );
415
  }
416
 
417
+ /**
418
+
419
+
420
  /**
421
  * Get WP_Object.
422
  *
inc/custom-post-types/course.php CHANGED
@@ -92,15 +92,20 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
92
  'items' => array(),
93
  ),
94
  'i18n' => array(
95
- 'item' => __( 'item', 'learnpress' ),
96
- 'new_section_item' => __( 'Create a new', 'learnpress' ),
97
- 'back' => __( 'Back', 'learnpress' ),
98
- 'selected_items' => __( 'Selected items', 'learnpress' ),
99
- 'confirm_trash_item' => __( 'Do you want to remove item "{{ITEM_NAME}}" to trash?', 'learnpress' ),
100
- 'item_labels' => array(
101
  'singular' => __( 'Item', 'learnpress' ),
102
  'plural' => __( 'Items', 'learnpress' ),
103
- )
 
 
 
 
 
104
  ),
105
  'sections' => array(
106
  'sections' => $course->get_curriculum_raw(),
@@ -628,6 +633,13 @@ if ( ! class_exists( 'LP_Course_Post_Type' ) ) {
628
  'type' => 'url',
629
  'desc' => __( 'Redirect to this url when you press button buy this course.', 'learnpress' ),
630
  'std' => '',
 
 
 
 
 
 
 
631
  )
632
  )
633
  );
92
  'items' => array(),
93
  ),
94
  'i18n' => array(
95
+ 'item' => __( 'item', 'learnpress' ),
96
+ 'new_section_item' => __( 'Create a new', 'learnpress' ),
97
+ 'back' => __( 'Back', 'learnpress' ),
98
+ 'selected_items' => __( 'Selected items', 'learnpress' ),
99
+ 'confirm_trash_item' => __( 'Do you want to remove item "{{ITEM_NAME}}" to trash?', 'learnpress' ),
100
+ 'item_labels' => array(
101
  'singular' => __( 'Item', 'learnpress' ),
102
  'plural' => __( 'Items', 'learnpress' ),
103
+ ),
104
+ 'notice_sale_price' => __( 'Course sale price must less than the regular price', 'learnpress' ),
105
+ 'notice_price' => __( 'Course price must greater than the sale price', 'learnpress' ),
106
+ 'notice_sale_start_date' => __( 'Sale start date must before sale end date', 'learnpress' ),
107
+ 'notice_sale_end_date' => __( 'Sale end date must before sale start date', 'learnpress' ),
108
+ 'notice_invalid_date' => __( 'Invalid date', 'learnpress' ),
109
  ),
110
  'sections' => array(
111
  'sections' => $course->get_curriculum_raw(),
633
  'type' => 'url',
634
  'desc' => __( 'Redirect to this url when you press button buy this course.', 'learnpress' ),
635
  'std' => '',
636
+ ),
637
+ array(
638
+ 'name' => __( 'Submission Form', 'learnpress' ),
639
+ 'id' => '_lp_submission',
640
+ 'type' => 'yes-no',
641
+ 'desc' => __( 'If this option is ON, then guess can click on the link of items but only see the submission form.', 'learnpress' ),
642
+ 'std' => 'yes'
643
  )
644
  )
645
  );
inc/custom-post-types/lesson.php CHANGED
@@ -261,23 +261,6 @@ if ( ! class_exists( 'LP_Lesson_Post_Type' ) ) {
261
  'type' => 'yes-no',
262
  'desc' => __( 'If this is a preview lesson, then student can view this lesson content without taking the course.', 'learnpress' ),
263
  'std' => 'no'
264
- ),
265
- array(
266
- 'name' => __( 'Submission Form', 'learnpress' ),
267
- 'id' => '_lp_submission',
268
- 'type' => 'yes-no',
269
- 'desc' => __( 'If this option is ON, then guess can click on the link of this lesson but only see the submission form.', 'learnpress' ),
270
- 'std' => 'no',
271
- 'visibility' => array(
272
- 'state' => 'show',
273
- 'conditional' => array(
274
- array(
275
- 'field' => '_lp_preview',
276
- 'compare' => '!=',
277
- 'value' => 'yes'
278
- )
279
- )
280
- )
281
  )
282
  )
283
  )
261
  'type' => 'yes-no',
262
  'desc' => __( 'If this is a preview lesson, then student can view this lesson content without taking the course.', 'learnpress' ),
263
  'std' => 'no'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
264
  )
265
  )
266
  )
inc/emails/_bk/class-lp-email-finished-course-admin.php ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class LP_Email_Finished_Course_Admin
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Classes
7
+ * @version 3.0.0
8
+ */
9
+
10
+ /**
11
+ * Prevent loading this file directly
12
+ */
13
+ defined( 'ABSPATH' ) || exit();
14
+
15
+ if ( ! class_exists( 'LP_Email_Finished_Course_Admin' ) ) {
16
+
17
+ /**
18
+ * Class LP_Email_Finished_Course_Admin
19
+ */
20
+ class LP_Email_Finished_Course_Admin extends LP_Email_Type_Finished_Course {
21
+ /**
22
+ * LP_Email_Finished_Course constructor.
23
+ */
24
+ public function __construct() {
25
+ $this->id = 'finished-course-admin';
26
+ $this->title = __( 'Admin', 'learnpress' );
27
+ $this->description = __( 'Send this email to user when a user finished a course.', 'learnpress' );
28
+
29
+
30
+ $this->default_subject = __( '[{{site_title}}] You have finished this course ({{course_name}})', 'learnpress' );
31
+ $this->default_heading = __( 'Finished course', 'learnpress' );
32
+
33
+ $this->support_variables = array_merge( $this->general_variables, array(
34
+ '{{course_id}}',
35
+ '{{course_name}}',
36
+ '{{course_url}}',
37
+ '{{user_id}}',
38
+ '{{user_name}}',
39
+ '{{user_email}}',
40
+ '{{user_profile_url}}'
41
+ ) );
42
+
43
+ //$this->email_text_message_description = sprintf( '%s {{course_id}}, {{course_title}}, {{course_url}}, {{user_email}}, {{user_name}}, {{user_profile_url}}', __( 'Shortcodes', 'learnpress' ) );
44
+
45
+ parent::__construct();
46
+ }
47
+
48
+ /**
49
+ * Trigger email.
50
+ *
51
+ * @param $course_id
52
+ * @param $user_id
53
+ * @param $result
54
+ *
55
+ * @return bool
56
+ */
57
+ public function trigger( $course_id, $user_id, $result ) {
58
+
59
+ if ( ! $this->enable || ! ( $user = learn_press_get_user( $user_id ) ) ) {
60
+ return false;
61
+ }
62
+
63
+ $course = learn_press_get_course( $course_id );
64
+ remove_filter( 'the_title', 'wptexturize' );
65
+ $course_name = $course->get_title();
66
+ add_filter( 'the_title', 'wptexturize' );
67
+
68
+ $this->object = $this->get_common_template_data(
69
+ $this->email_format,
70
+ array(
71
+ 'course_id' => $course_id,
72
+ 'course_name' => $course_name,
73
+ 'course_url' => get_the_permalink( $course_id ),
74
+ 'user_id' => $user_id,
75
+ 'user_name' => learn_press_get_profile_display_name( $user ),
76
+ 'user_email' => $user->user_email,
77
+ 'user_profile_url' => learn_press_user_profile_link( $user->get_id() )
78
+ )
79
+ );
80
+
81
+ $this->variables = $this->data_to_variables( $this->object );
82
+
83
+ $this->object['course'] = $course;
84
+ $this->object['user'] = $user;
85
+
86
+ $this->recipient = $user->user_email;
87
+
88
+ $return = $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
89
+
90
+ return $return;
91
+ }
92
+
93
+
94
+ /**
95
+ * Get recipient.
96
+ *
97
+ * @return mixed|void
98
+ */
99
+ public function get_recipient() {
100
+ if ( ! empty( $this->object['user'] ) ) {
101
+ $this->recipient = $this->object['user']->user_email;
102
+ }
103
+
104
+ parent::get_recipient();
105
+ }
106
+
107
+ /**
108
+ * Get email template.
109
+ *
110
+ * @param string $content_type
111
+ *
112
+ * @return array|object
113
+ */
114
+ public function get_template_data( $content_type = 'plain' ) {
115
+ return $this->object;
116
+ }
117
+
118
+ /**
119
+ * Admin settings.
120
+ */
121
+ public function get_settings() {
122
+ return apply_filters(
123
+ 'learn-press/email-settings/finished-course/settings',
124
+ array(
125
+ array(
126
+ 'type' => 'heading',
127
+ 'title' => $this->title,
128
+ 'desc' => $this->description
129
+ ),
130
+ array(
131
+ 'title' => __( 'Enable', 'learnpress' ),
132
+ 'type' => 'yes-no',
133
+ 'default' => 'no',
134
+ 'id' => $this->get_field_name( 'enable' )
135
+ ),
136
+ array(
137
+ 'title' => __( 'Subject', 'learnpress' ),
138
+ 'type' => 'text',
139
+ 'default' => $this->default_subject,
140
+ 'id' => $this->get_field_name( 'subject' ),
141
+ 'desc' => sprintf( __( 'Email subject, default: <code>%s</code>.', 'learnpress' ), $this->default_subject ),
142
+ 'visibility' => array(
143
+ 'state' => 'show',
144
+ 'conditional' => array(
145
+ array(
146
+ 'field' => $this->get_field_name( 'enable' ),
147
+ 'compare' => '=',
148
+ 'value' => 'yes'
149
+ )
150
+ )
151
+ )
152
+ ),
153
+ array(
154
+ 'title' => __( 'Heading', 'learnpress' ),
155
+ 'type' => 'text',
156
+ 'default' => $this->default_heading,
157
+ 'id' => $this->get_field_name( 'heading' ),
158
+ 'desc' => sprintf( __( 'Email heading, default: <code>%s</code>.', 'learnpress' ), $this->default_heading ),
159
+ 'visibility' => array(
160
+ 'state' => 'show',
161
+ 'conditional' => array(
162
+ array(
163
+ 'field' => $this->get_field_name( 'enable' ),
164
+ 'compare' => '=',
165
+ 'value' => 'yes'
166
+ )
167
+ )
168
+ )
169
+ ),
170
+ array(
171
+ 'title' => __( 'Email content', 'learnpress' ),
172
+ 'type' => 'email-content',
173
+ 'default' => '',
174
+ 'id' => $this->get_field_name( 'email_content' ),
175
+ 'template_base' => $this->template_base,
176
+ 'template_path' => $this->template_path,//default learnpress
177
+ 'template_html' => $this->template_html,
178
+ 'template_plain' => $this->template_plain,
179
+ 'template_html_local' => $this->get_theme_template_file( 'html', $this->template_path ),
180
+ 'template_plain_local' => $this->get_theme_template_file( 'plain', $this->template_path ),
181
+ 'support_variables' => $this->get_variables_support(),
182
+ 'visibility' => array(
183
+ 'state' => 'show',
184
+ 'conditional' => array(
185
+ array(
186
+ 'field' => $this->get_field_name( 'enable' ),
187
+ 'compare' => '=',
188
+ 'value' => 'yes'
189
+ )
190
+ )
191
+ )
192
+ ),
193
+ )
194
+ );
195
+ }
196
+ }
197
+ }
198
+
199
+ return new LP_Email_Finished_Course_Admin();
inc/emails/_bk/class-lp-email-finished-course-instructor.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class LP_Email_Finished_Course_Instructor
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Classes
7
+ * @version 3.0.0
8
+ */
9
+
10
+ /**
11
+ * Prevent loading this file directly
12
+ */
13
+ defined( 'ABSPATH' ) || exit();
14
+
15
+ if ( ! class_exists( 'LP_Email_Finished_Course_Instructor' ) ) {
16
+
17
+ /**
18
+ * Class LP_Email_Finished_Course_Instructor
19
+ */
20
+ class LP_Email_Finished_Course_Instructor extends LP_Email {
21
+ /**
22
+ * LP_Email_Finished_Course constructor.
23
+ */
24
+ public function __construct() {
25
+ $this->id = 'finished-course-instructor';
26
+ $this->title = __( 'Instructor', 'learnpress' );
27
+ $this->description = __( 'Send this email to user when a user finished a course.', 'learnpress' );
28
+
29
+ $this->template_html = 'emails/finished-course.php';
30
+ $this->template_plain = 'emails/plain/finished-course.php';
31
+
32
+ $this->default_subject = __( '[{{site_title}}] You have finished this course ({{course_name}})', 'learnpress' );
33
+ $this->default_heading = __( 'Finished course', 'learnpress' );
34
+
35
+ $this->support_variables = array_merge( $this->general_variables, array(
36
+ '{{course_id}}',
37
+ '{{course_name}}',
38
+ '{{course_url}}',
39
+ '{{user_id}}',
40
+ '{{user_name}}',
41
+ '{{user_email}}',
42
+ '{{user_profile_url}}'
43
+ ) );
44
+
45
+ //$this->email_text_message_description = sprintf( '%s {{course_id}}, {{course_title}}, {{course_url}}, {{user_email}}, {{user_name}}, {{user_profile_url}}', __( 'Shortcodes', 'learnpress' ) );
46
+
47
+ parent::__construct();
48
+ }
49
+
50
+ /**
51
+ * Trigger email.
52
+ *
53
+ * @param $course_id
54
+ * @param $user_id
55
+ * @param $result
56
+ *
57
+ * @return bool
58
+ */
59
+ public function trigger( $course_id, $user_id, $result ) {
60
+
61
+ if ( ! $this->enable || ! ( $user = learn_press_get_user( $user_id ) ) ) {
62
+ return false;
63
+ }
64
+
65
+ $course = learn_press_get_course( $course_id );
66
+ remove_filter( 'the_title', 'wptexturize' );
67
+ $course_name = $course->get_title();
68
+ add_filter( 'the_title', 'wptexturize' );
69
+
70
+ $this->object = $this->get_common_template_data(
71
+ $this->email_format,
72
+ array(
73
+ 'course_id' => $course_id,
74
+ 'course_name' => $course_name,
75
+ 'course_url' => get_the_permalink( $course_id ),
76
+ 'user_id' => $user_id,
77
+ 'user_name' => learn_press_get_profile_display_name( $user ),
78
+ 'user_email' => $user->user_email,
79
+ 'user_profile_url' => learn_press_user_profile_link( $user->get_id() )
80
+ )
81
+ );
82
+
83
+ $this->variables = $this->data_to_variables( $this->object );
84
+
85
+ $this->object['course'] = $course;
86
+ $this->object['user'] = $user;
87
+
88
+ $this->recipient = $user->user_email;
89
+
90
+ $return = $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
91
+
92
+ return $return;
93
+ }
94
+
95
+
96
+ /**
97
+ * Get recipient.
98
+ *
99
+ * @return mixed|void
100
+ */
101
+ public function get_recipient() {
102
+ if ( ! empty( $this->object['user'] ) ) {
103
+ $this->recipient = $this->object['user']->user_email;
104
+ }
105
+
106
+ parent::get_recipient();
107
+ }
108
+
109
+ /**
110
+ * Get email template.
111
+ *
112
+ * @param string $content_type
113
+ *
114
+ * @return array|object
115
+ */
116
+ public function get_template_data( $content_type = 'plain' ) {
117
+ return $this->object;
118
+ }
119
+
120
+ /**
121
+ * Admin settings.
122
+ */
123
+ public function get_settings() {
124
+ return apply_filters(
125
+ 'learn-press/email-settings/finished-course/settings',
126
+ array(
127
+ array(
128
+ 'type' => 'heading',
129
+ 'title' => $this->title,
130
+ 'desc' => $this->description
131
+ ),
132
+ array(
133
+ 'title' => __( 'Enable', 'learnpress' ),
134
+ 'type' => 'yes-no',
135
+ 'default' => 'no',
136
+ 'id' => $this->get_field_name( 'enable' )
137
+ ),
138
+ array(
139
+ 'title' => __( 'Subject', 'learnpress' ),
140
+ 'type' => 'text',
141
+ 'default' => $this->default_subject,
142
+ 'id' => $this->get_field_name( 'subject' ),
143
+ 'desc' => sprintf( __( 'Email subject, default: <code>%s</code>.', 'learnpress' ), $this->default_subject ),
144
+ 'visibility' => array(
145
+ 'state' => 'show',
146
+ 'conditional' => array(
147
+ array(
148
+ 'field' => $this->get_field_name( 'enable' ),
149
+ 'compare' => '=',
150
+ 'value' => 'yes'
151
+ )
152
+ )
153
+ )
154
+ ),
155
+ array(
156
+ 'title' => __( 'Heading', 'learnpress' ),
157
+ 'type' => 'text',
158
+ 'default' => $this->default_heading,
159
+ 'id' => $this->get_field_name( 'heading' ),
160
+ 'desc' => sprintf( __( 'Email heading, default: <code>%s</code>.', 'learnpress' ), $this->default_heading ),
161
+ 'visibility' => array(
162
+ 'state' => 'show',
163
+ 'conditional' => array(
164
+ array(
165
+ 'field' => $this->get_field_name( 'enable' ),
166
+ 'compare' => '=',
167
+ 'value' => 'yes'
168
+ )
169
+ )
170
+ )
171
+ ),
172
+ array(
173
+ 'title' => __( 'Email content', 'learnpress' ),
174
+ 'type' => 'email-content',
175
+ 'default' => '',
176
+ 'id' => $this->get_field_name( 'email_content' ),
177
+ 'template_base' => $this->template_base,
178
+ 'template_path' => $this->template_path,//default learnpress
179
+ 'template_html' => $this->template_html,
180
+ 'template_plain' => $this->template_plain,
181
+ 'template_html_local' => $this->get_theme_template_file( 'html', $this->template_path ),
182
+ 'template_plain_local' => $this->get_theme_template_file( 'plain', $this->template_path ),
183
+ 'support_variables' => $this->get_variables_support(),
184
+ 'visibility' => array(
185
+ 'state' => 'show',
186
+ 'conditional' => array(
187
+ array(
188
+ 'field' => $this->get_field_name( 'enable' ),
189
+ 'compare' => '=',
190
+ 'value' => 'yes'
191
+ )
192
+ )
193
+ )
194
+ ),
195
+ )
196
+ );
197
+ }
198
+ }
199
+ }
200
+
201
+ return new LP_Email_Finished_Course_Instructor();
inc/emails/_bk/class-lp-email-finished-course-user.php ADDED
@@ -0,0 +1,201 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class LP_Email_Finished_Course_User
4
+ *
5
+ * @author ThimPress
6
+ * @package LearnPress/Classes
7
+ * @version 3.0.0
8
+ */
9
+
10
+ /**
11
+ * Prevent loading this file directly
12
+ */
13
+ defined( 'ABSPATH' ) || exit();
14
+
15
+ if ( ! class_exists( 'LP_Email_Finished_Course_User' ) ) {
16
+
17
+ /**
18
+ * Class LP_Email_Finished_Course_User
19
+ */
20
+ class LP_Email_Finished_Course_User extends LP_Email {
21
+ /**
22
+ * LP_Email_Finished_Course constructor.
23
+ */
24
+ public function __construct() {
25
+ $this->id = 'finished-course-user';
26
+ $this->title = __( 'User', 'learnpress' );
27
+ $this->description = __( 'Send this email to user when a user finished a course.', 'learnpress' );
28
+
29
+ $this->template_html = 'emails/finished-course.php';
30
+ $this->template_plain = 'emails/plain/finished-course.php';
31
+
32
+ $this->default_subject = __( '[{{site_title}}] You have finished this course ({{course_name}})', 'learnpress' );
33
+ $this->default_heading = __( 'Finished course', 'learnpress' );
34
+
35
+ $this->support_variables = array_merge( $this->general_variables, array(
36
+ '{{course_id}}',
37
+ '{{course_name}}',
38
+ '{{course_url}}',
39
+ '{{user_id}}',
40
+ '{{user_name}}',
41
+ '{{user_email}}',
42
+ '{{user_profile_url}}'
43
+ ) );
44
+
45
+ //$this->email_text_message_description = sprintf( '%s {{course_id}}, {{course_title}}, {{course_url}}, {{user_email}}, {{user_name}}, {{user_profile_url}}', __( 'Shortcodes', 'learnpress' ) );
46
+
47
+ parent::__construct();
48
+ }
49
+
50
+ /**
51
+ * Trigger email.
52
+ *
53
+ * @param $course_id
54
+ * @param $user_id
55
+ * @param $result
56
+ *
57
+ * @return bool
58
+ */
59
+ public function trigger( $course_id, $user_id, $result ) {
60
+
61
+ if ( ! $this->enable || ! ( $user = learn_press_get_user( $user_id ) ) ) {
62
+ return false;
63
+ }
64
+
65
+ $course = learn_press_get_course( $course_id );
66
+ remove_filter( 'the_title', 'wptexturize' );
67
+ $course_name = $course->get_title();
68
+ add_filter( 'the_title', 'wptexturize' );
69
+
70
+ $this->object = $this->get_common_template_data(
71
+ $this->email_format,
72
+ array(
73
+ 'course_id' => $course_id,
74
+ 'course_name' => $course_name,
75
+ 'course_url' => get_the_permalink( $course_id ),
76
+ 'user_id' => $user_id,
77
+ 'user_name' => learn_press_get_profile_display_name( $user ),
78
+ 'user_email' => $user->user_email,
79
+ 'user_profile_url' => learn_press_user_profile_link( $user->get_id() )
80
+ )
81
+ );
82
+
83
+ $this->variables = $this->data_to_variables( $this->object );
84
+
85
+ $this->object['course'] = $course;
86
+ $this->object['user'] = $user;
87
+
88
+ $this->recipient = $user->user_email;
89
+
90
+ $return = $this->send( $this->get_recipient(), $this->get_subject(), $this->get_content(), $this->get_headers(), $this->get_attachments() );
91
+
92
+ return $return;
93
+ }
94
+
95
+
96
+ /**
97
+ * Get recipient.
98
+ *
99
+ * @return mixed|void
100
+ */
101
+ public function get_recipient() {
102
+ if ( ! empty( $this->object['user'] ) ) {
103
+ $this->recipient = $this->object['user']->user_email;
104
+ }
105
+
106
+ parent::get_recipient();
107
+ }
108
+
109
+ /**
110
+ * Get email template.
111
+ *
112
+ * @param string $content_type
113
+ *
114
+ * @return array|object
115
+ */
116
+ public function get_template_data( $content_type = 'plain' ) {
117
+ return $this->object;
118
+ }
119
+
120
+ /**
121
+ * Admin settings.
122
+ */
123
+ public function get_settings() {
124
+ return apply_filters(
125
+ 'learn-press/email-settings/finished-course/settings',
126
+ array(
127
+ array(
128
+ 'type' => 'heading',
129
+ 'title' => $this->title,
130
+ 'desc' => $this->description
131
+ ),
132
+ array(
133
+ 'title' => __( 'Enable', 'learnpress' ),
134
+ 'type' => 'yes-no',
135
+ 'default' => 'no',
136
+ 'id' => $this->get_field_name( 'enable' )
137
+ ),
138
+ array(
139
+ 'title' => __( 'Subject', 'learnpress' ),
140
+ 'type' => 'text',
141
+ 'default' => $this->default_subject,
142
+ 'id' => $this->get_field_name( 'subject' ),
143
+ 'desc' => sprintf( __( 'Email subject, default: <code>%s</code>.', 'learnpress' ), $this->default_subject ),
144
+ 'visibility' => array(
145
+ 'state' => 'show',
146
+ 'conditional' => array(
147
+ array(
148
+ 'field' => $this->get_field_name( 'enable' ),
149
+ 'compare' => '=',
150
+ 'value' => 'yes'
151
+ )
152
+ )
153
+ )
154
+ ),
155
+ array(
156
+ 'title' => __( 'Heading', 'learnpress' ),
157
+ 'type' => 'text',
158
+ 'default' => $this->default_heading,
159
+ 'id' => $this->get_field_name( 'heading' ),
160
+ 'desc' => sprintf( __( 'Email heading, default: <code>%s</code>.', 'learnpress' ), $this->default_heading ),
161
+ 'visibility' => array(
162
+ 'state' => 'show',
163
+ 'conditional' => array(
164
+ array(
165
+ 'field' => $this->get_field_name( 'enable' ),
166
+ 'compare' => '=',
167
+ 'value' => 'yes'
168
+ )
169
+ )
170
+ )
171
+ ),
172
+ array(
173
+ 'title' => __( 'Email content', 'learnpress' ),
174
+ 'type' => 'email-content',
175
+ 'default' => '',
176
+ 'id' => $this->get_field_name( 'email_content' ),
177
+ 'template_base' => $this->template_base,
178
+ 'template_path' => $this->template_path,//default learnpress
179
+ 'template_html' => $this->template_html,
180
+ 'template_plain' => $this->template_plain,
181
+ 'template_html_local' => $this->get_theme_template_file( 'html', $this->template_path ),
182
+ 'template_plain_local' => $this->get_theme_template_file( 'plain', $this->template_path ),
183
+ 'support_variables' => $this->get_variables_support(),
184
+ 'visibility' => array(
185
+ 'state' => 'show',
186
+ 'conditional' => array(
187
+ array(
188
+ 'field' => $this->get_field_name( 'enable' ),
189
+ 'compare' => '=',
190
+ 'value' => 'yes'
191
+ )
192
+ )
193
+ )
194
+ ),
195
+ )
196
+ );
197
+ }
198
+ }
199
+ }
200
+
201
+ return new LP_Email_Finished_Course_User();
inc/emails/types/class-lp-email-type-finished-course.php CHANGED
@@ -56,6 +56,7 @@ class LP_Email_Type_Finished_Course extends LP_Email {
56
  print_r( $this );
57
  die();
58
  }
 
59
  $course = learn_press_get_course( $this->course_id );
60
  $course_data = $user->get_course_data( $this->course_id );
61
  $object = array();
56
  print_r( $this );
57
  die();
58
  }
59
+ wp_cache_delete( 'course-' . $user->get_id() . '-' . $this->course_id, 'lp-user-course-data' );
60
  $course = learn_press_get_course( $this->course_id );
61
  $course_data = $user->get_course_data( $this->course_id );
62
  $object = array();
inc/gateways/paypal/class-lp-gateway-paypal.php CHANGED
@@ -233,7 +233,7 @@ if ( ! class_exists( 'LP_Gateway_Paypal' ) ) {
233
  $order_key = $custom->order_key;
234
 
235
  // Fallback to serialized data if safe. This is @deprecated in 2.3.11
236
- } elseif ( preg_match( '/^a:2:{/', $raw_custom ) && ! preg_match( '/[CO]:\+?[0-9]+:"/', $raw_custom ) && ( $custom = maybe_unserialize( $raw_custom ) ) ) {
237
  $order_id = $custom[0];
238
  $order_key = $custom[1];
239
 
233
  $order_key = $custom->order_key;
234
 
235
  // Fallback to serialized data if safe. This is @deprecated in 2.3.11
236
+ } elseif ( preg_match( '/^a:2:{/', $raw_custom ) && ! preg_match( '/[CO]:\+?[0-9]+:"/', $raw_custom ) && ( $custom = LP_Helper::maybe_unserialize( $raw_custom ) ) ) {
237
  $order_id = $custom[0];
238
  $order_key = $custom[1];
239
 
inc/libraries/meta-box/css/image-advanced.css ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Image */
2
+ .rwmb-image-item {
3
+ position: relative;
4
+ float: left;
5
+ padding: 0;
6
+ margin: 0 5px 5px 0;
7
+ box-sizing: border-box;
8
+ }
9
+ .rwmb-image-item.thumbnail .rwmb-media-preview,
10
+ .rwmb-image-item.thumbnail{
11
+ width: 150px;
12
+ }
13
+ .rwmb-image-item.medium .rwmb-media-preview,
14
+ .rwmb-image-item.medium {
15
+ width: 300px;
16
+ }
17
+ .rwmb-image-item.large .rwmb-media-preview,
18
+ .rwmb-image-item.large {
19
+ width: 1024px;
20
+ }
21
+
22
+ .rwmb-image-item .dashicons {
23
+ font-size: 20px;
24
+ width: 20px;
25
+ height: 20px;
26
+ }
27
+ .rwmb-media-bar {
28
+ position: absolute;
29
+ z-index: 10;
30
+ display: none;
31
+ right: 5px;
32
+ top: 5px;
33
+ color: #fff;
34
+ }
35
+ .rwmb-media-bar a {
36
+ text-decoration: none;
37
+ color: inherit;
38
+ }
39
+ .rwmb-overlay {
40
+ position: absolute;
41
+ top: 0;
42
+ bottom: 0;
43
+ left: 0;
44
+ right: 0;
45
+ background: rgba(0, 0, 0, .6);
46
+ display: none;
47
+ }
48
+ .rwmb-image-item:hover .rwmb-media-bar,
49
+ .rwmb-image-item:hover .rwmb-overlay {
50
+ display: block;
51
+ cursor: move;
52
+ }
inc/libraries/meta-box/img/loader.gif ADDED
Binary file
inc/libraries/meta-box/inc/fields/thickbox-image.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Image upload field which uses thickbox library to upload.
4
+ *
5
+ * @package Meta Box
6
+ * @deprecated Use image_advanced instead
7
+ */
8
+
9
+ /**
10
+ * The thickbox image field class.
11
+ */
12
+ class RWMB_Thickbox_Image_Field extends RWMB_Image_Field {
13
+ /**
14
+ * Add custom actions for the field.
15
+ */
16
+ public static function add_actions() {
17
+ parent::add_actions();
18
+ add_filter( 'get_media_item_args', array( __CLASS__, 'allow_img_insertion' ) );
19
+ }
20
+
21
+ /**
22
+ * Always enable insert to post button in the popup.
23
+ *
24
+ * @link https://github.com/rilwis/meta-box/issues/809
25
+ * @link http://wordpress.stackexchange.com/q/22175/2051
26
+ * @param array $vars Media item arguments in the popup.
27
+ * @return array
28
+ */
29
+ public static function allow_img_insertion( $vars ) {
30
+ $vars['send'] = true; // 'send' as in "Send to Editor".
31
+ return $vars;
32
+ }
33
+
34
+ /**
35
+ * Enqueue scripts and styles.
36
+ */
37
+ public static function admin_enqueue_scripts() {
38
+ parent::admin_enqueue_scripts();
39
+
40
+ add_thickbox();
41
+ wp_enqueue_script( 'media-upload' );
42
+
43
+ wp_enqueue_script( 'rwmb-thickbox-image', RWMB_JS_URL . 'thickbox-image.js', array( 'jquery' ), RWMB_VER, true );
44
+ }
45
+
46
+ /**
47
+ * Get field HTML.
48
+ *
49
+ * @param mixed $meta Meta value.
50
+ * @param array $field Field parameters.
51
+ *
52
+ * @return string
53
+ */
54
+ public static function html( $meta, $field ) {
55
+ $i18n_title = apply_filters( 'rwmb_thickbox_image_upload_string', _x( 'Upload Images', 'image upload', 'meta-box' ), $field );
56
+
57
+ // Uploaded images.
58
+ $html = parent::get_uploaded_files( $meta, $field );
59
+
60
+ // Show form upload.
61
+ $html .= "<a href='#' class='button rwmb-thickbox-upload' data-field_id='{$field['id']}'>{$i18n_title}</a>";
62
+
63
+ return $html;
64
+ }
65
+
66
+ /**
67
+ * Get field value.
68
+ * It's the combination of new (uploaded) images and saved images.
69
+ *
70
+ * @param mixed $new The submitted meta value.
71
+ * @param mixed $old The existing meta value.
72
+ * @param int $post_id The post ID.
73
+ * @param array $field The field parameters.
74
+ *
75
+ * @return array
76
+ */
77
+ public static function value( $new, $old, $post_id, $field ) {
78
+ return array_filter( array_unique( array_merge( (array) $old, (array) $new ) ) );
79
+ }
80
+ }
inc/libraries/meta-box/js/thickbox-image.js ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ jQuery( function ( $ ) {
2
+ 'use strict';
3
+
4
+ $( 'body' ).on( 'click', '.rwmb-thickbox-upload', function () {
5
+ var $this = $( this ),
6
+ $holder = $this.siblings( '.rwmb-images' ),
7
+ post_id = $( '#post_ID' ).val(),
8
+ field_id = $this.data( 'field_id' ),
9
+ backup = window.send_to_editor;
10
+
11
+ window.send_to_editor = function ( html ) {
12
+ var $img = $( '<div />' ).append( html ).find( 'img' ),
13
+ url = $img.attr( 'src' ),
14
+ img_class = $img.attr( 'class' ),
15
+ id = parseInt( img_class.replace( /\D/g, '' ), 10 );
16
+
17
+ html = '<li id="item_' + id + '">';
18
+ html += '<img src="' + url + '">';
19
+ html += '<div class="rwmb-image-bar">';
20
+ html += '<a class="rwmb-delete-file" href="#" data-attachment_id="' + id + '">×</a>';
21
+ html += '</div>';
22
+ html += '<input type="hidden" name="' + field_id + '[]" value="' + id + '">';
23
+ html += '</li>';
24
+
25
+ $holder.append( $( html ) ).removeClass( 'hidden' );
26
+
27
+ tb_remove();
28
+ window.send_to_editor = backup;
29
+ };
30
+ tb_show( '', 'media-upload.php?post_id=' + post_id + '&TB_iframe=true' );
31
+
32
+ return false;
33
+ } );
34
+ } );
inc/libraries/wp-background-process.php CHANGED
@@ -280,7 +280,7 @@ abstract class WP_Background_Process extends WP_Async_Request {
280
  if( $query ){
281
  $batch = new stdClass();
282
  $batch->key = $query->$column;
283
- $batch->data = maybe_unserialize( $query->$value_column );
284
  }
285
  return $batch;
286
  }
280
  if( $query ){
281
  $batch = new stdClass();
282
  $batch->key = $query->$column;
283
+ $batch->data = LP_Helper::maybe_unserialize( $query->$value_column );
284
  }
285
  return $batch;
286
  }
inc/lp-constants.php CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
- define( 'LEARNPRESS_VERSION', '3.0.8' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
+ define( 'LEARNPRESS_VERSION', '3.0.9' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
inc/lp-core-functions.php CHANGED
@@ -3186,7 +3186,7 @@ function learn_press_remove_user_items_history( $item_id, $course_id, $user_id,
3186
  * @return array
3187
  */
3188
  function learn_press_get_block_course_item_types() {
3189
- return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT ) );
3190
  }
3191
 
3192
  //add_filter('learn-press/block-course-item-types', function ($a){
3186
  * @return array
3187
  */
3188
  function learn_press_get_block_course_item_types() {
3189
+ return apply_filters( 'learn-press/block-course-item-types', array( LP_LESSON_CPT, LP_QUIZ_CPT ) );
3190
  }
3191
 
3192
  //add_filter('learn-press/block-course-item-types', function ($a){
inc/lp-template-functions.php CHANGED
@@ -886,6 +886,10 @@ if ( ! function_exists( 'learn_press_quiz_start_button' ) ) {
886
  ) {
887
  return;
888
  }
 
 
 
 
889
  learn_press_get_template( 'content-quiz/buttons/start.php' );
890
  }
891
  }
@@ -1929,10 +1933,10 @@ if ( ! function_exists( 'learn_press_course_lesson_class' ) ) {
1929
  /**
1930
  * The class of lesson in course curriculum
1931
  *
1932
- * @param int $lesson_id
1933
- * @param int $course_id
1934
  * @param array|string $class
1935
- * @param boolean $echo
1936
  *
1937
  * @return mixed
1938
  */
@@ -1992,10 +1996,10 @@ if ( ! function_exists( 'learn_press_course_quiz_class' ) ) {
1992
  /**
1993
  * The class of lesson in course curriculum
1994
  *
1995
- * @param int $quiz_id
1996
- * @param int $course_id
1997
  * @param string|array $class
1998
- * @param boolean $echo
1999
  *
2000
  * @return mixed
2001
  */
@@ -2169,9 +2173,9 @@ function learn_press_get_messages( $clear = false ) {
2169
  /**
2170
  * Add new message into queue for displaying.
2171
  *
2172
- * @param string $message
2173
- * @param string $type
2174
- * @param array $options
2175
  * @param int|bool $current_user . @since 3.0.9 - add for current user only
2176
  */
2177
  function learn_press_add_message( $message, $type = 'success', $options = array(), $current_user = true ) {
@@ -2219,7 +2223,7 @@ function learn_press_get_message( $message, $type = 'success' ) {
2219
  *
2220
  * @since 3.0.0
2221
  *
2222
- * @param string $id
2223
  * @param string|array $type
2224
  */
2225
  function learn_press_remove_message( $id = '', $type = '' ) {
@@ -2468,9 +2472,9 @@ function learn_press_get_template_part( $slug, $name = '' ) {
2468
  * Get other templates passing attributes and including the file.
2469
  *
2470
  * @param string $template_name
2471
- * @param array $args (default: array())
2472
  * @param string $template_path (default: '')
2473
- * @param string $default_path (default: '')
2474
  *
2475
  * @return void
2476
  */
@@ -2492,12 +2496,13 @@ function learn_press_get_template( $template_name, $args = array(), $template_pa
2492
  }
2493
  // Allow 3rd party plugin filter template file from their plugin
2494
  $located = apply_filters( 'learn_press_get_template', $located, $template_name, $args, $template_path, $default_path );
 
 
2495
 
2496
- do_action( 'learn_press_before_template_part', $template_name, $template_path, $located, $args );
2497
 
2498
- include( $located );
2499
-
2500
- do_action( 'learn_press_after_template_part', $template_name, $template_path, $located, $args );
2501
  }
2502
 
2503
  /**
@@ -2506,7 +2511,7 @@ function learn_press_get_template( $template_name, $args = array(), $template_pa
2506
  * @uses learn_press_get_template();
2507
  *
2508
  * @param $template_name
2509
- * @param array $args
2510
  * @param string $template_path
2511
  * @param string $default_path
2512
  *
@@ -2532,7 +2537,7 @@ function learn_press_get_template_content( $template_name, $args = array(), $tem
2532
  *
2533
  * @param string $template_name
2534
  * @param string $template_path (default: '')
2535
- * @param string $default_path (default: '')
2536
  *
2537
  * @return string
2538
  */
@@ -3694,4 +3699,49 @@ function learn_press_content_item_summary_classes( $classes ) {
3694
  }
3695
 
3696
  return $classes;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3697
  }
886
  ) {
887
  return;
888
  }
889
+
890
+ if ( ! $user->has_course_status( $course->get_id(), array( 'enrolled' ) ) && $course->is_required_enroll() ) {
891
+ return;
892
+ }
893
  learn_press_get_template( 'content-quiz/buttons/start.php' );
894
  }
895
  }
1933
  /**
1934
  * The class of lesson in course curriculum
1935
  *
1936
+ * @param int $lesson_id
1937
+ * @param int $course_id
1938
  * @param array|string $class
1939
+ * @param boolean $echo
1940
  *
1941
  * @return mixed
1942
  */
1996
  /**
1997
  * The class of lesson in course curriculum
1998
  *
1999
+ * @param int $quiz_id
2000
+ * @param int $course_id
2001
  * @param string|array $class
2002
+ * @param boolean $echo
2003
  *
2004
  * @return mixed
2005
  */
2173
  /**
2174
  * Add new message into queue for displaying.
2175
  *
2176
+ * @param string $message
2177
+ * @param string $type
2178
+ * @param array $options
2179
  * @param int|bool $current_user . @since 3.0.9 - add for current user only
2180
  */
2181
  function learn_press_add_message( $message, $type = 'success', $options = array(), $current_user = true ) {
2223
  *
2224
  * @since 3.0.0
2225
  *
2226
+ * @param string $id
2227
  * @param string|array $type
2228
  */
2229
  function learn_press_remove_message( $id = '', $type = '' ) {
2472
  * Get other templates passing attributes and including the file.
2473
  *
2474
  * @param string $template_name
2475
+ * @param array $args (default: array())
2476
  * @param string $template_path (default: '')
2477
+ * @param string $default_path (default: '')
2478
  *
2479
  * @return void
2480
  */
2496
  }
2497
  // Allow 3rd party plugin filter template file from their plugin
2498
  $located = apply_filters( 'learn_press_get_template', $located, $template_name, $args, $template_path, $default_path );
2499
+ if ( $located != '' ) {
2500
+ do_action( 'learn_press_before_template_part', $template_name, $template_path, $located, $args );
2501
 
2502
+ include( $located );
2503
 
2504
+ do_action( 'learn_press_after_template_part', $template_name, $template_path, $located, $args );
2505
+ }
 
2506
  }
2507
 
2508
  /**
2511
  * @uses learn_press_get_template();
2512
  *
2513
  * @param $template_name
2514
+ * @param array $args
2515
  * @param string $template_path
2516
  * @param string $default_path
2517
  *
2537
  *
2538
  * @param string $template_name
2539
  * @param string $template_path (default: '')
2540
+ * @param string $default_path (default: '')
2541
  *
2542
  * @return string
2543
  */
3699
  }
3700
 
3701
  return $classes;
3702
+ }
3703
+
3704
+ function learn_press_maybe_load_comment_js() {
3705
+ if ( $item = LP_Global::course_item() ) {
3706
+ wp_enqueue_script( 'comment-reply' );
3707
+ }
3708
+ }
3709
+
3710
+ add_action( 'wp_enqueue_scripts', 'learn_press_maybe_load_comment_js' );
3711
+
3712
+ add_filter( 'learn-press/can-view-item', 'learn_press_filter_can_view_item', 10, 4 );
3713
+
3714
+ function learn_press_filter_can_view_item( $view, $item_id, $course_id, $user_id ) {
3715
+ $user = learn_press_get_user( $user_id );
3716
+
3717
+ if ( ! get_post_meta( $course_id, '_lp_submission', true ) ) {
3718
+ update_post_meta( $course_id, '_lp_submission', 'yes' );
3719
+ }
3720
+ $_lp_submission = get_post_meta( $course_id, '_lp_submission', true );
3721
+ if ( $_lp_submission === 'yes' ) {
3722
+ if ( ! $user->is_logged_in() ) {
3723
+ return 'not-logged-in';
3724
+ } else if ( ! $user->has_enrolled_course( $course_id ) ) {
3725
+ return 'not-enrolled';
3726
+ }
3727
+ }
3728
+
3729
+ return $view;
3730
+ }
3731
+
3732
+ add_filter( 'learn_press_get_template', 'learn_press_filter_block_content_template', 10, 5 );
3733
+
3734
+ function learn_press_filter_block_content_template( $located, $template_name, $args, $template_path, $default_path ) {
3735
+
3736
+ if ( $template_name == 'global/block-content.php' ) {
3737
+ if ( ! is_user_logged_in() ) {
3738
+ $can_view_item = 'not-logged-in';
3739
+ } elseif ( ! learn_press_current_user_enrolled_course() ) {
3740
+ $can_view_item = 'not-enrolled';
3741
+ }
3742
+ $located = learn_press_get_template( 'single-course/content-protected.php', array( 'can_view_item' => $can_view_item ) );
3743
+ }
3744
+
3745
+ return $located;
3746
+
3747
  }
inc/order/class-lp-order.php CHANGED
@@ -553,7 +553,7 @@ if ( ! class_exists( 'LP_Order' ) ) {
553
  public function get_item_meta( &$item ) {
554
  if ( $metas = get_metadata( 'learnpress_order_item', $item['id'] ) ) {
555
  foreach ( $metas as $k => $v ) {
556
- $item[ preg_replace( '!^_!', '', $k ) ] = maybe_unserialize( $v[0] );
557
  }
558
  };
559
  }
553
  public function get_item_meta( &$item ) {
554
  if ( $metas = get_metadata( 'learnpress_order_item', $item['id'] ) ) {
555
  foreach ( $metas as $k => $v ) {
556
+ $item[ preg_replace( '!^_!', '', $k ) ] = LP_Helper::maybe_unserialize( $v[0] );
557
  }
558
  };
559
  }
inc/updates/_update-from-0.9.php CHANGED
@@ -912,7 +912,7 @@ class LP_Upgrade_From_09 {
912
  if ( $order_meta ) {
913
  foreach ( $order_meta as $meta ) {
914
  if ( '_learn_press_order_items' == $meta['meta_key'] ) {
915
- $order_data = maybe_unserialize( $meta['meta_value'] );
916
  if ( isset( $order_data->total ) ) {
917
  add_post_meta( $new_id, '_order_total', $order_data->total );
918
  } else {
@@ -1155,7 +1155,7 @@ class LP_Upgrade_From_09 {
1155
  $origin_type = gettype( $meta );
1156
  $meta = (array) $meta;
1157
  foreach ( $meta as $k => $v ) {
1158
- $meta[ $k ] = maybe_unserialize( $v );
1159
  }
1160
  settype( $meta, $origin_type );
1161
 
912
  if ( $order_meta ) {
913
  foreach ( $order_meta as $meta ) {
914
  if ( '_learn_press_order_items' == $meta['meta_key'] ) {
915
+ $order_data = LP_Helper::maybe_unserialize( $meta['meta_value'] );
916
  if ( isset( $order_data->total ) ) {
917
  add_post_meta( $new_id, '_order_total', $order_data->total );
918
  } else {
1155
  $origin_type = gettype( $meta );
1156
  $meta = (array) $meta;
1157
  foreach ( $meta as $k => $v ) {
1158
+ $meta[ $k ] = LP_Helper::maybe_unserialize( $v );
1159
  }
1160
  settype( $meta, $origin_type );
1161
 
inc/user-item/class-lp-user-item-course.php CHANGED
@@ -154,7 +154,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
154
  $this->add_meta( $result );
155
  } else {
156
  $item = $this->get_item( $item_id );
157
- $result->meta_value = maybe_unserialize( $result->meta_value );
158
 
159
  $item->add_meta( $result );
160
  }
@@ -596,7 +596,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
596
  /**
597
  * Get all items in course.
598
  *
599
- * @return array
600
  */
601
  public function get_items() {
602
  return $this->_items;
154
  $this->add_meta( $result );
155
  } else {
156
  $item = $this->get_item( $item_id );
157
+ $result->meta_value = LP_Helper::maybe_unserialize( $result->meta_value );
158
 
159
  $item->add_meta( $result );
160
  }
596
  /**
597
  * Get all items in course.
598
  *
599
+ * @return LP_User_Item[]
600
  */
601
  public function get_items() {
602
  return $this->_items;
inc/user-item/class-lp-user-item.php CHANGED
@@ -224,7 +224,7 @@ class LP_User_Item extends LP_Abstract_Object_Data {
224
 
225
  if ( $results = $wpdb->get_results( $query ) ) {
226
  foreach ( $results as $result ) {
227
- $result->meta_value = maybe_unserialize( $result->meta_value );
228
  $this->_meta_data[] = $result;
229
  }
230
  }
@@ -235,30 +235,6 @@ class LP_User_Item extends LP_Abstract_Object_Data {
235
  return learn_press_get_user_item_meta( $this->get_user_item_id(), $key, $single );
236
  }
237
 
238
- // public function set_meta_data( $key, $value ) {
239
- // if ( empty( $this->_meta_data ) ) {
240
- // $this->_meta_data = array();
241
- // }
242
- // $set = false;
243
- // if ( $this->_meta_data ) {
244
- // foreach ( $this->_meta_data as $k => $v ) {
245
- // if ( $k === $v->meta_key ) {
246
- // $this->_meta_data[ $k ]->meta_value = $value;
247
- // $set = true;
248
- // break;
249
- // }
250
- // }
251
- // }
252
- //
253
- // if ( ! $set ) {
254
- // $this->_meta_data[] = (object) array(
255
- // 'meta_key' => $key,
256
- // 'meta_value' => $value
257
- // );
258
- // }
259
- //
260
- // }
261
-
262
  public function update_meta() {
263
  if ( $this->_meta_data ) {
264
  foreach ( $this->_meta_data as $meta_data ) {
224
 
225
  if ( $results = $wpdb->get_results( $query ) ) {
226
  foreach ( $results as $result ) {
227
+ $result->meta_value = LP_Helper::maybe_unserialize( $result->meta_value );
228
  $this->_meta_data[] = $result;
229
  }
230
  }
235
  return learn_press_get_user_item_meta( $this->get_user_item_id(), $key, $single );
236
  }
237
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
238
  public function update_meta() {
239
  if ( $this->_meta_data ) {
240
  foreach ( $this->_meta_data as $meta_data ) {
inc/user/abstract-lp-user.php CHANGED
@@ -105,7 +105,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
105
  /**
106
  * LP_Abstract_User constructor.
107
  *
108
- * @param int $the_user
109
  * @param array $args
110
  */
111
  public function __construct( $the_user = 0, $args = array() ) {
@@ -147,7 +147,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
147
  * Get data for a course user has enrolled.
148
  *
149
  * @param int|LP_Abstract_Course $course_id
150
- * @param bool $check_exists
151
  *
152
  * @return LP_User_Item_Course|LP_User_Item_Quiz|bool
153
  */
@@ -261,7 +261,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
261
  * Check if a course is exists then return it's ID.
262
  * Try to get it from global.
263
  *
264
- * @param int $course_id
265
  * @param string $return
266
  *
267
  * @return bool|false|int|LP_Course
@@ -307,8 +307,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
307
  * Return TRUE if an item has a status.
308
  *
309
  * @param array $statuses
310
- * @param int $item_id
311
- * @param int $course_id
312
  *
313
  * @return mixed
314
  *
@@ -324,8 +324,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
324
  /**
325
  * Get all records of an item.
326
  *
327
- * @param int $item_id
328
- * @param int $course_id
329
  * @param bool $return_last
330
  *
331
  * @return bool|mixed
@@ -365,8 +365,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
365
  /**
366
  * Start quiz for the user.
367
  *
368
- * @param int $quiz_id
369
- * @param int $course_id
370
  * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
371
  *
372
  * @throws Exception
@@ -427,8 +427,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
427
  * @since 3.0.0
428
  */
429
  do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
430
- }
431
- catch ( Exception $ex ) {
432
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
433
  }
434
 
@@ -438,8 +437,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
438
  /**
439
  * Finish a quiz for the user and save all data needed
440
  *
441
- * @param int $quiz_id
442
- * @param int $course_id
443
  * @param bool $wp_error
444
  *
445
  * @return mixed
@@ -478,8 +477,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
478
  do_action( 'learn_press_user_finish_quiz', $quiz_id, $this->get_id() );
479
 
480
  do_action( 'learn-press/user/quiz-finished', $quiz_id, $course_id, $this->get_id() );
481
- }
482
- catch ( Exception $ex ) {
483
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
484
  }
485
 
@@ -489,8 +487,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
489
  /**
490
  * Retake a quiz for the user
491
  *
492
- * @param int $quiz_id
493
- * @param int $course_id
494
  * @param bool $wp_error
495
  *
496
  * @return bool|WP_Error
@@ -533,8 +531,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
533
  * @since 3.0.0
534
  */
535
  do_action( 'learn-press/user/quiz-redone', $quiz_id, $course_id, $this->get_id() );
536
- }
537
- catch ( Exception $ex ) {
538
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
539
  do_action( 'learn-press/user/retake-quiz-failure', $quiz_id, $course_id, $this->get_id() );
540
  }
@@ -566,14 +563,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
566
  if ( $last_results && $last_results['status'] === 'completed' ) {
567
  $course_data->update_item_retaken_count( $quiz_id, '+1' );
568
  }
569
- //die();
570
- //// var_dump( $this->count_item_archive( $quiz_id, $course_id ) );
571
- //// var_dump( $this->can_retake_quiz( $quiz_id, $course_id ) );
572
- ////
573
- //// var_dump( current_filter() );
574
- //// var_dump( current_action() );
575
- //
576
- // die();
577
  $start_time = new LP_Datetime( current_time( 'mysql' ) );
578
  $item_data = array(
579
  'user_id' => $this->get_id(),
@@ -629,92 +619,16 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
629
  $course_id = $this->_get_course( $course_id );
630
  $remaining = false;
631
  $progress = $this->get_quiz_progress( $quiz_id, $course_id );
632
- # Debug
633
- if ( isset( $_GET['lp_debug'] ) && $_GET['lp_debug'] == 'time_remaining' ) {
634
- $time = time();
635
- $ctime = current_time( "timestamp" );
636
- $ctime_true = current_time( "timestamp", true );
637
-
638
- $ctime_sql = current_time( "mysql" );
639
- $ctime_sql_true = current_time( "mysql", true );
640
-
641
- echo '<table border="1">';
642
-
643
- echo '<tr><td>$time: <br/>time();</td><td>' . $time . '</td></tr>';
644
- echo '<tr><td>$ctime: <br/>current_time("timestamp");</td><td>' . $ctime . '</td></tr>';
645
- echo '<tr><td>$ctime_true:<br/>current_time("timestamp", true); </td><td>' . $ctime_true . '</td></tr>';
646
- echo '<tr><td>$ctime_sql: <br/>current_time("mysql")</td><td>' . $ctime_sql . '</td></tr>';
647
- echo '<tr><td>strtotime($ctime_sql):</td><td>' . strtotime( $ctime_sql ) . '</td></tr>';
648
- echo '<tr><td>$ctime_sql_true:<br/>current_time("mysql", true) </td><td>' . $ctime_sql_true . '</td></tr>';
649
- echo '<tr><td>strtotime($ctime_sql_true):</td><td>' . strtotime( $ctime_sql_true ) . '</td></tr>';
650
- echo '</table>';
651
- // exit();
652
- }
653
  if ( $progress && $progress->status != 'completed' ) {
654
  $quiz = LP_Quiz::get_quiz( $quiz_id );
655
- // $current_time = current_time( 'timestamp' );
656
  $current_time = learn_press_get_current_time();
657
  $progress_start = strtotime( $progress->start, $current_time );
658
  $remaining = intval( $quiz->get_duration() ) + $progress_start - $current_time;
659
- if ( isset( $_GET['lp_debug'] ) && $_GET['lp_debug'] == 'time_remaining' ) {
660
- echo '<hr/>$current_time: ' . $current_time;
661
- echo '<hr/>$progress_start: ' . $progress_start;
662
- echo '<hr/>$quiz->get_duration(): ' . intval( $quiz->get_duration() );
663
- echo '<hr/>$remaining: ' . $remaining;
664
- }
665
- }
666
- if ( isset( $_GET['lp_debug'] ) && $_GET['lp_debug'] == 'time_remaining' ) {
667
- echo '<hr/>$remaining: ' . $remaining;
668
- exit();
669
  }
670
-
671
  return apply_filters( 'learn_press_user_quiz_time_remaining', $remaining, $quiz_id, $course_id, $this->get_id() );
672
  }
673
 
674
- public function get_current_question_id( $quiz_id = 0 ) {
675
-
676
- _deprecated_function( __CLASS__ . "::" . __FUNCTION__, '3.0.8' );
677
- $current = false;
678
- $quiz_current_question = $this->quiz_current_question;
679
- if ( is_array( $quiz_current_question ) && ! empty( $quiz_current_question[ $quiz_id ] ) ) {
680
- $current = $quiz_current_question[ $quiz_id ];
681
- } else {
682
- $quiz_questions = $this->quiz_questions;
683
- if ( is_array( $quiz_questions ) && ! empty( $quiz_questions[ $quiz_id ] ) ) {
684
- $current = $quiz_questions[ $quiz_id ];
685
- }
686
- }
687
- if ( ! $current ) {
688
- $history = $this->get_quiz_history( $quiz_id );
689
-
690
- if ( $history ) {
691
- $keys = array_keys( $history );
692
- //$current = learn_press_get_user_quiz_meta( $keys[0], 'current_question' );
693
- }
694
- }
695
-
696
- return $current;
697
- }
698
-
699
- public function get_current_question_x( $quiz_id, $what = '' ) {
700
- $current = $this->get_current_question_id( $quiz_id );
701
- if ( $what == 'id' ) {
702
- return $current;
703
- } else {
704
- $question = LP_Question::get_question( $current );
705
- switch ( $what ) {
706
- case 'html':
707
- if ( $question ) {
708
- ob_start();
709
- $question->render();
710
- $current = ob_get_clean();
711
- }
712
- }
713
- }
714
-
715
- return $current;
716
- }
717
-
718
  public function get_question_answers( $question_id, $quiz_id, $course_id = 0 ) {
719
  $course_id = $this->_get_course( $course_id );
720
 
@@ -757,8 +671,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
757
  }
758
 
759
  /**
760
- * @param int $item_id
761
- * @param int $course_id
762
  * @param bool $last
763
  *
764
  * @since 3.0.0
@@ -809,8 +723,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
809
  /**
810
  * Get current status of an item for user.
811
  *
812
- * @param int $item_id
813
- * @param int $course_id
814
  * @param bool $force
815
  *
816
  * @return bool|mixed
@@ -966,8 +880,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
966
  /**
967
  * Get current question's ID/Permalink inside quiz.
968
  *
969
- * @param int $quiz_id
970
- * @param int $course_id
971
  * @param bool $permalink
972
  *
973
  * @return bool|int|string
@@ -1022,9 +936,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1022
  * Checks if has status of a quiz for user
1023
  *
1024
  * @param string|array $statuses
1025
- * @param int $quiz_id
1026
- * @param int $course_id
1027
- * @param boolean $force
1028
  *
1029
  * @return bool
1030
  */
@@ -1040,8 +954,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1040
  /**
1041
  * Get current results of a quiz
1042
  *
1043
- * @param int $quiz_id
1044
- * @param int $course_id
1045
  * @param string $prop
1046
  *
1047
  * @return mixed
@@ -1076,8 +990,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1076
  * @since 3.0.0
1077
  *
1078
  * @param int $question_id
1079
- * @param int $quiz_id
1080
- * @param int $course_id
1081
  *
1082
  * @return WP_Error|mixed
1083
  */
@@ -1107,8 +1021,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1107
  * @since 3.0.0
1108
  *
1109
  * @param int $question_id
1110
- * @param int $quiz_id
1111
- * @param int $course_id
1112
  *
1113
  * @return WP_Error|mixed
1114
  */
@@ -1231,9 +1145,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1231
  /**
1232
  * Get history of a quiz for an user
1233
  *
1234
- * @param int $quiz_id
1235
- * @param int $course_id
1236
- * @param int $history_id
1237
  * @param bool $force
1238
  *
1239
  * @return mixed|null|void
@@ -1317,7 +1231,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1317
  if ( ! $obj_key ) {
1318
  continue;
1319
  }
1320
- $history[ $_key ][ $v->user_item_id ]->{$obj_key} = maybe_unserialize( $v->meta_value );
1321
  }
1322
  }
1323
  }
@@ -1606,6 +1520,14 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1606
  $return = false;
1607
  $course_id = $this->_get_course( $course_id );
1608
 
 
 
 
 
 
 
 
 
1609
  switch ( get_post_type( $item_id ) ) {
1610
  case LP_QUIZ_CPT:
1611
  $return = $this->can_view_quiz( $item_id, $course_id );
@@ -1664,10 +1586,6 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1664
  } elseif ( ! $course->is_required_enroll() ) {
1665
  // if course is not required enroll so the lesson is previewable
1666
  $view = 'no-required-enroll';
1667
- } elseif( ! $this->is_logged_in() ){
1668
- $view = 'not-logged-in';
1669
- } elseif( ! $this->has_enrolled_course( $course_id ) ){
1670
- $view = 'not-enrolled';
1671
  }
1672
  }
1673
  }
@@ -1774,7 +1692,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1774
  * - started: value of column `status` in user_items is started
1775
  * - enrolled: value of column `status` in user_items is enrolled
1776
  *
1777
- * @param int $course_id
1778
  * @param string|array $statuses
1779
  *
1780
  * @since 2.0
@@ -1947,7 +1865,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1947
  /**
1948
  * Return true if user has already enrolled course
1949
  *
1950
- * @param int $course_id
1951
  * @param bool $force
1952
  *
1953
  * @return bool
@@ -2058,8 +1976,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2058
 
2059
 
2060
  /**
2061
- * @param int $quiz_id
2062
- * @param int $course_id
2063
  * @param bool $force
2064
  *
2065
  * @return mixed
@@ -2092,8 +2010,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2092
  /**
2093
  * Count number of time user has retaken a quiz
2094
  *
2095
- * @param int $quiz_id
2096
- * @param int $course_id
2097
  * @param bool $force
2098
  *
2099
  * @return int
@@ -2137,7 +2055,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2137
  /**
2138
  * Count number of time user has retaken a quiz
2139
  *
2140
- * @param int $course_id
2141
  * @param bool $force
2142
  *
2143
  * @return int
@@ -2320,9 +2238,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2320
  /**
2321
  * Return current status of course for user
2322
  *
2323
- * @param int $course_id
2324
  * @param string $field
2325
- * @param bool $force
2326
  *
2327
  * @return mixed
2328
  */
@@ -2453,7 +2371,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2453
 
2454
  /**
2455
  * @param $item
2456
- * @param int $course_id
2457
  * @param bool $force
2458
  *
2459
  * @return mixed|void
@@ -2514,7 +2432,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2514
  /**
2515
  * Get the order that contains the course.
2516
  *
2517
- * @param int $course_id
2518
  * @param string $return type of order to return LP_Order|ID
2519
  *
2520
  * @return int|LP_Order|mixed
@@ -2621,8 +2539,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2621
  //}
2622
 
2623
  return $return;
2624
- }
2625
- catch ( Exception $ex ) {
2626
  return new WP_Error( $ex->getCode(), $ex->getMessage() );
2627
  }
2628
  }
@@ -2800,7 +2717,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2800
 
2801
  /**
2802
  * @param string $type
2803
- * @param int $size
2804
  *
2805
  * @return false|string
2806
  */
105
  /**
106
  * LP_Abstract_User constructor.
107
  *
108
+ * @param int $the_user
109
  * @param array $args
110
  */
111
  public function __construct( $the_user = 0, $args = array() ) {
147
  * Get data for a course user has enrolled.
148
  *
149
  * @param int|LP_Abstract_Course $course_id
150
+ * @param bool $check_exists
151
  *
152
  * @return LP_User_Item_Course|LP_User_Item_Quiz|bool
153
  */
261
  * Check if a course is exists then return it's ID.
262
  * Try to get it from global.
263
  *
264
+ * @param int $course_id
265
  * @param string $return
266
  *
267
  * @return bool|false|int|LP_Course
307
  * Return TRUE if an item has a status.
308
  *
309
  * @param array $statuses
310
+ * @param int $item_id
311
+ * @param int $course_id
312
  *
313
  * @return mixed
314
  *
324
  /**
325
  * Get all records of an item.
326
  *
327
+ * @param int $item_id
328
+ * @param int $course_id
329
  * @param bool $return_last
330
  *
331
  * @return bool|mixed
365
  /**
366
  * Start quiz for the user.
367
  *
368
+ * @param int $quiz_id
369
+ * @param int $course_id
370
  * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
371
  *
372
  * @throws Exception
427
  * @since 3.0.0
428
  */
429
  do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
430
+ } catch ( Exception $ex ) {
 
431
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
432
  }
433
 
437
  /**
438
  * Finish a quiz for the user and save all data needed
439
  *
440
+ * @param int $quiz_id
441
+ * @param int $course_id
442
  * @param bool $wp_error
443
  *
444
  * @return mixed
477
  do_action( 'learn_press_user_finish_quiz', $quiz_id, $this->get_id() );
478
 
479
  do_action( 'learn-press/user/quiz-finished', $quiz_id, $course_id, $this->get_id() );
480
+ } catch ( Exception $ex ) {
 
481
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
482
  }
483
 
487
  /**
488
  * Retake a quiz for the user
489
  *
490
+ * @param int $quiz_id
491
+ * @param int $course_id
492
  * @param bool $wp_error
493
  *
494
  * @return bool|WP_Error
531
  * @since 3.0.0
532
  */
533
  do_action( 'learn-press/user/quiz-redone', $quiz_id, $course_id, $this->get_id() );
534
+ } catch ( Exception $ex ) {
 
535
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
536
  do_action( 'learn-press/user/retake-quiz-failure', $quiz_id, $course_id, $this->get_id() );
537
  }
563
  if ( $last_results && $last_results['status'] === 'completed' ) {
564
  $course_data->update_item_retaken_count( $quiz_id, '+1' );
565
  }
566
+
 
 
 
 
 
 
 
567
  $start_time = new LP_Datetime( current_time( 'mysql' ) );
568
  $item_data = array(
569
  'user_id' => $this->get_id(),
619
  $course_id = $this->_get_course( $course_id );
620
  $remaining = false;
621
  $progress = $this->get_quiz_progress( $quiz_id, $course_id );
622
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
623
  if ( $progress && $progress->status != 'completed' ) {
624
  $quiz = LP_Quiz::get_quiz( $quiz_id );
 
625
  $current_time = learn_press_get_current_time();
626
  $progress_start = strtotime( $progress->start, $current_time );
627
  $remaining = intval( $quiz->get_duration() ) + $progress_start - $current_time;
 
 
 
 
 
 
 
 
 
 
628
  }
 
629
  return apply_filters( 'learn_press_user_quiz_time_remaining', $remaining, $quiz_id, $course_id, $this->get_id() );
630
  }
631
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
632
  public function get_question_answers( $question_id, $quiz_id, $course_id = 0 ) {
633
  $course_id = $this->_get_course( $course_id );
634
 
671
  }
672
 
673
  /**
674
+ * @param int $item_id
675
+ * @param int $course_id
676
  * @param bool $last
677
  *
678
  * @since 3.0.0
723
  /**
724
  * Get current status of an item for user.
725
  *
726
+ * @param int $item_id
727
+ * @param int $course_id
728
  * @param bool $force
729
  *
730
  * @return bool|mixed
880
  /**
881
  * Get current question's ID/Permalink inside quiz.
882
  *
883
+ * @param int $quiz_id
884
+ * @param int $course_id
885
  * @param bool $permalink
886
  *
887
  * @return bool|int|string
936
  * Checks if has status of a quiz for user
937
  *
938
  * @param string|array $statuses
939
+ * @param int $quiz_id
940
+ * @param int $course_id
941
+ * @param boolean $force
942
  *
943
  * @return bool
944
  */
954
  /**
955
  * Get current results of a quiz
956
  *
957
+ * @param int $quiz_id
958
+ * @param int $course_id
959
  * @param string $prop
960
  *
961
  * @return mixed
990
  * @since 3.0.0
991
  *
992
  * @param int $question_id
993
+ * @param int $quiz_id
994
+ * @param int $course_id
995
  *
996
  * @return WP_Error|mixed
997
  */
1021
  * @since 3.0.0
1022
  *
1023
  * @param int $question_id
1024
+ * @param int $quiz_id
1025
+ * @param int $course_id
1026
  *
1027
  * @return WP_Error|mixed
1028
  */
1145
  /**
1146
  * Get history of a quiz for an user
1147
  *
1148
+ * @param int $quiz_id
1149
+ * @param int $course_id
1150
+ * @param int $history_id
1151
  * @param bool $force
1152
  *
1153
  * @return mixed|null|void
1231
  if ( ! $obj_key ) {
1232
  continue;
1233
  }
1234
+ $history[ $_key ][ $v->user_item_id ]->{$obj_key} = LP_Helper::maybe_unserialize( $v->meta_value );
1235
  }
1236
  }
1237
  }
1520
  $return = false;
1521
  $course_id = $this->_get_course( $course_id );
1522
 
1523
+ $course_author = learn_press_get_course_user( $course_id );
1524
+ if ( $course_author ) {
1525
+ $author_id = $course_author->get_id();
1526
+ if ( $author_id == $this->get_id() ) {
1527
+ return true;
1528
+ }
1529
+ }
1530
+
1531
  switch ( get_post_type( $item_id ) ) {
1532
  case LP_QUIZ_CPT:
1533
  $return = $this->can_view_quiz( $item_id, $course_id );
1586
  } elseif ( ! $course->is_required_enroll() ) {
1587
  // if course is not required enroll so the lesson is previewable
1588
  $view = 'no-required-enroll';
 
 
 
 
1589
  }
1590
  }
1591
  }
1692
  * - started: value of column `status` in user_items is started
1693
  * - enrolled: value of column `status` in user_items is enrolled
1694
  *
1695
+ * @param int $course_id
1696
  * @param string|array $statuses
1697
  *
1698
  * @since 2.0
1865
  /**
1866
  * Return true if user has already enrolled course
1867
  *
1868
+ * @param int $course_id
1869
  * @param bool $force
1870
  *
1871
  * @return bool
1976
 
1977
 
1978
  /**
1979
+ * @param int $quiz_id
1980
+ * @param int $course_id
1981
  * @param bool $force
1982
  *
1983
  * @return mixed
2010
  /**
2011
  * Count number of time user has retaken a quiz
2012
  *
2013
+ * @param int $quiz_id
2014
+ * @param int $course_id
2015
  * @param bool $force
2016
  *
2017
  * @return int
2055
  /**
2056
  * Count number of time user has retaken a quiz
2057
  *
2058
+ * @param int $course_id
2059
  * @param bool $force
2060
  *
2061
  * @return int
2238
  /**
2239
  * Return current status of course for user
2240
  *
2241
+ * @param int $course_id
2242
  * @param string $field
2243
+ * @param bool $force
2244
  *
2245
  * @return mixed
2246
  */
2371
 
2372
  /**
2373
  * @param $item
2374
+ * @param int $course_id
2375
  * @param bool $force
2376
  *
2377
  * @return mixed|void
2432
  /**
2433
  * Get the order that contains the course.
2434
  *
2435
+ * @param int $course_id
2436
  * @param string $return type of order to return LP_Order|ID
2437
  *
2438
  * @return int|LP_Order|mixed
2539
  //}
2540
 
2541
  return $return;
2542
+ } catch ( Exception $ex ) {
 
2543
  return new WP_Error( $ex->getCode(), $ex->getMessage() );
2544
  }
2545
  }
2717
 
2718
  /**
2719
  * @param string $type
2720
+ * @param int $size
2721
  *
2722
  * @return false|string
2723
  */
inc/user/class-lp-profile.php CHANGED
@@ -671,7 +671,7 @@ if ( ! class_exists( 'LP_Profile' ) ) {
671
  *
672
  * @param string $args
673
  *
674
- * @return array
675
  */
676
  public function query_orders( $args = '' ) {
677
  global $wp_query;
@@ -748,6 +748,8 @@ if ( ! class_exists( 'LP_Profile' ) ) {
748
  );
749
  }
750
 
 
 
751
  }
752
 
753
  return $query;
671
  *
672
  * @param string $args
673
  *
674
+ * @return LP_Query_List_Table
675
  */
676
  public function query_orders( $args = '' ) {
677
  global $wp_query;
748
  );
749
  }
750
 
751
+ }else{
752
+ $query = new LP_Query_List_Table($query);
753
  }
754
 
755
  return $query;
learnpress.php CHANGED
@@ -4,10 +4,10 @@ Plugin Name: LearnPress
4
  Plugin URI: http://thimpress.com/learnpress
5
  Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
6
  Author: ThimPress
7
- Version: 3.0.8
8
  Author URI: http://thimpress.com
9
  Requires at least: 3.8
10
- Tested up to: 4.9.4
11
 
12
  Text Domain: learnpress
13
  Domain Path: /languages/
@@ -215,6 +215,7 @@ if ( ! class_exists( 'LearnPress' ) ) {
215
  * Includes needed files.
216
  */
217
  public function includes() {
 
218
  require_once 'inc/class-lp-settings.php';
219
  require_once 'inc/class-lp-factory.php';
220
  require_once 'inc/class-lp-datetime.php';
@@ -262,7 +263,7 @@ if ( ! class_exists( 'LearnPress' ) ) {
262
  require_once 'inc/lp-webhooks.php';
263
  require_once 'inc/class-lp-request-handler.php';
264
  require_once( 'inc/abstract-settings.php' );
265
- require_once( 'inc/class-lp-market-products.php' );
266
 
267
  if ( is_admin() ) {
268
  require_once 'inc/admin/meta-box/class-lp-meta-box-helper.php';
@@ -296,6 +297,7 @@ if ( ! class_exists( 'LearnPress' ) ) {
296
  require_once 'inc/lesson/lp-lesson-functions.php';
297
  require_once 'inc/order/lp-order-functions.php';
298
  require_once 'inc/order/class-lp-order.php';
 
299
 
300
  // user API
301
  require_once 'inc/user/lp-user-functions.php';
4
  Plugin URI: http://thimpress.com/learnpress
5
  Description: LearnPress is a WordPress complete solution for creating a Learning Management System (LMS). It can help you to create courses, lessons and quizzes.
6
  Author: ThimPress
7
+ Version: 3.0.9
8
  Author URI: http://thimpress.com
9
  Requires at least: 3.8
10
+ Tested up to: 4.9.6
11
 
12
  Text Domain: learnpress
13
  Domain Path: /languages/
215
  * Includes needed files.
216
  */
217
  public function includes() {
218
+ require_once 'inc/class-lp-helper.php';
219
  require_once 'inc/class-lp-settings.php';
220
  require_once 'inc/class-lp-factory.php';
221
  require_once 'inc/class-lp-datetime.php';
263
  require_once 'inc/lp-webhooks.php';
264
  require_once 'inc/class-lp-request-handler.php';
265
  require_once( 'inc/abstract-settings.php' );
266
+ //require_once( 'inc/class-lp-market-products.php' );
267
 
268
  if ( is_admin() ) {
269
  require_once 'inc/admin/meta-box/class-lp-meta-box-helper.php';
297
  require_once 'inc/lesson/lp-lesson-functions.php';
298
  require_once 'inc/order/lp-order-functions.php';
299
  require_once 'inc/order/class-lp-order.php';
300
+ require_once 'inc/class-lp-gdpr.php';
301
 
302
  // user API
303
  require_once 'inc/user/lp-user-functions.php';
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link:
4
  Tags: WordPress LMS, LMS, eLearning, e-Learning, Learning Management System, LMS WordPress, Course, Courses, Quiz, Quizzes, Training, Guru, Sell Courses
5
  Requires at least: 3.8
6
  Tested up to: 4.9.5
7
- Stable tag: 3.0.8
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
@@ -199,6 +199,12 @@ https://www.transifex.com/projects/p/learnpress/
199
  8. Add-ons of LearnPress.
200
 
201
  == Changelog ==
 
 
 
 
 
 
202
  = 3.0.8 =
203
  ~ Improved: get css class name for items for performance
204
  ~ Improved: check item is blocked for performance
4
  Tags: WordPress LMS, LMS, eLearning, e-Learning, Learning Management System, LMS WordPress, Course, Courses, Quiz, Quizzes, Training, Guru, Sell Courses
5
  Requires at least: 3.8
6
  Tested up to: 4.9.5
7
+ Stable tag: 3.0.9
8
  License: GPLv2 or later
9
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
10
 
199
  8. Add-ons of LearnPress.
200
 
201
  == Changelog ==
202
+ = 3.0.9 =
203
+ + GDPR compliance
204
+ ~ Improved Start quiz button
205
+ ~ Load js for comment-reply if it does not load by default
206
+ ~ Fixed missing param when sending email for user who finished course
207
+
208
  = 3.0.8 =
209
  ~ Improved: get css class name for items for performance
210
  ~ Improved: check item is blocked for performance
templates/content-lesson/block-content.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Template for displaying block lesson content.
4
+ *
5
+ * This template can be overridden by copying it to yourtheme/learnpress/content-lesson/block-content.php.
6
+ *
7
+ * @author ThimPress
8
+ * @package Learnpress/Templates
9
+ * @version 3.0.0
10
+ */
11
+
12
+ /**
13
+ * Prevent loading this file directly
14
+ */
15
+ defined( 'ABSPATH' ) || exit();
16
+
17
+ learn_press_display_message( __( 'This lesson has been locked', 'learnpress' ), 'error' );
templates/content-quiz/buttons/start.php CHANGED
@@ -20,17 +20,17 @@ $quiz = LP_Global::course_item_quiz();
20
 
21
  <?php do_action( 'learn-press/before-quiz-start-button' ); ?>
22
 
23
- <form name="start-quiz" class="start-quiz" method="post" enctype="multipart/form-data">
24
 
25
- <?php do_action( 'learn-press/begin-quiz-start-button' ); ?>
26
 
27
- <button type="submit" class="button"><?php _e( 'Start', 'learnpress' ); ?></button>
28
 
29
- <?php do_action( 'learn-press/end-quiz-start-button' ); ?>
30
 
31
- <?php LP_Nonce_Helper::quiz_action( 'start', $quiz->get_id(), $course->get_id(), true ); ?>
32
- <input type="hidden" name="noajax" value="yes">
33
 
34
- </form>
35
 
36
- <?php do_action( 'learn-press/after-quiz-start-button' ); ?>
20
 
21
  <?php do_action( 'learn-press/before-quiz-start-button' ); ?>
22
 
23
+ <form name="start-quiz" class="start-quiz" method="post" enctype="multipart/form-data">
24
 
25
+ <?php do_action( 'learn-press/begin-quiz-start-button' ); ?>
26
 
27
+ <button type="submit" class="button"><?php _e( 'Start', 'learnpress' ); ?></button>
28
 
29
+ <?php do_action( 'learn-press/end-quiz-start-button' ); ?>
30
 
31
+ <?php LP_Nonce_Helper::quiz_action( 'start', $quiz->get_id(), $course->get_id(), true ); ?>
32
+ <input type="hidden" name="noajax" value="yes">
33
 
34
+ </form>
35
 
36
+ <?php do_action( 'learn-press/after-quiz-start-button' ); ?>
templates/profile/content.php CHANGED
@@ -21,6 +21,7 @@ if ( ! isset( $user ) ) {
21
  $profile = learn_press_get_profile();
22
  $tabs = $profile->get_tabs();
23
  $current = $profile->get_current_tab();
 
24
  ?>
25
  <div id="learn-press-profile-content" class="lp-profile-content">
26
 
21
  $profile = learn_press_get_profile();
22
  $tabs = $profile->get_tabs();
23
  $current = $profile->get_current_tab();
24
+
25
  ?>
26
  <div id="learn-press-profile-content" class="lp-profile-content">
27
 
templates/single-course/content-item.php CHANGED
@@ -6,7 +6,7 @@
6
  *
7
  * @author ThimPress
8
  * @package Learnpress/Templates
9
- * @version 3.0.0
10
  */
11
 
12
  /**
@@ -14,14 +14,10 @@
14
  */
15
  defined( 'ABSPATH' ) || exit();
16
 
17
- $user = LP_Global::user();
18
- $course_item = LP_Global::course_item();
19
- $course = LP_Global::course();
20
- $can_view_item = $user->can_view_item( $course_item->get_id(), $course->get_id() );
21
- $exclude_cases = apply_filters( 'learn_press/exclude_view_cases', array(
22
- 'not-logged-in',
23
- 'not-enrolled'
24
- ) );
25
  ?>
26
 
27
  <div id="learn-press-content-item">
@@ -44,7 +40,7 @@ $exclude_cases = apply_filters( 'learn_press/exclude_view_cases', array(
44
  */
45
  do_action( 'learn-press/before-course-item-content' );
46
 
47
- if ( $can_view_item && ! in_array( $can_view_item, $exclude_cases ) ) {
48
  /**
49
  * @deprecated
50
  */
@@ -56,7 +52,7 @@ $exclude_cases = apply_filters( 'learn_press/exclude_view_cases', array(
56
  do_action( 'learn-press/course-item-content' );
57
 
58
  } else {
59
- learn_press_get_template( 'single-course/content-protected.php', array( 'can_view_item'=>$can_view_item ) );
60
  }
61
 
62
  /**
6
  *
7
  * @author ThimPress
8
  * @package Learnpress/Templates
9
+ * @version 3.0.9
10
  */
11
 
12
  /**
14
  */
15
  defined( 'ABSPATH' ) || exit();
16
 
17
+ $user = LP_Global::user();
18
+ $course_item = LP_Global::course_item();
19
+ $course = LP_Global::course();
20
+ $can_view_item = $user->can_view_item( $course_item->get_id(), $course->get_id() );
 
 
 
 
21
  ?>
22
 
23
  <div id="learn-press-content-item">
40
  */
41
  do_action( 'learn-press/before-course-item-content' );
42
 
43
+ if ( $can_view_item ) {
44
  /**
45
  * @deprecated
46
  */
52
  do_action( 'learn-press/course-item-content' );
53
 
54
  } else {
55
+ learn_press_get_template( 'single-course/content-protected.php', array( 'can_view_item' => $can_view_item ) );
56
  }
57
 
58
  /**