LearnPress – WordPress LMS Plugin - Version 3.2.5

Version Description

~ Fixed button for creating LP pages does not work properly. ~ Fixed warning when getting course items does not exists. ~ Added button to close warning for outdated templates. ~ Fixed search order not working. ~ Fixed get course items in incorrect order. ~ Fixed can't start quiz when the course is not required enroll. ~ Fixed the amount number of enrolled users isn't updated correctly.

Download this release

Release Info

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

Code changes from version 3.2.4 to 3.2.5

assets/css/admin/admin.css CHANGED
@@ -3156,25 +3156,32 @@ body.lp-item-moving {
3156
  .button.disabled {
3157
  pointer-events: none; }
3158
 
3159
- .lp-notice h4,
3160
- .learn-press-notice h4 {
3161
- margin: 10px 0 15px; }
3162
-
3163
- .lp-notice p,
3164
- .learn-press-notice p {
3165
- margin: 0 0 5px 0;
3166
- padding: 0 2px; }
3167
-
3168
- .lp-notice.lp-upgrade-notice,
3169
- .learn-press-notice.lp-upgrade-notice {
3170
- background: #BCEFFE;
3171
- border-left-color: #02B7FB;
3172
- position: relative; }
3173
- .lp-notice.lp-upgrade-notice .close-notice,
3174
- .learn-press-notice.lp-upgrade-notice .close-notice {
 
 
 
 
 
 
 
3175
  position: absolute;
3176
- top: 5px;
3177
- right: 10px; }
3178
 
3179
  .learn-press-dropdown-pages {
3180
  display: inline-block; }
3156
  .button.disabled {
3157
  pointer-events: none; }
3158
 
3159
+ .lp-notice,
3160
+ .learn-press-notice {
3161
+ position: relative;
3162
+ padding: 12px; }
3163
+ .lp-notice h4,
3164
+ .learn-press-notice h4 {
3165
+ margin: 10px 0 15px; }
3166
+ .lp-notice p,
3167
+ .learn-press-notice p {
3168
+ margin: 0 0 5px 0;
3169
+ padding: 0 2px; }
3170
+ .lp-notice.lp-upgrade-notice,
3171
+ .learn-press-notice.lp-upgrade-notice {
3172
+ background: #BCEFFE;
3173
+ border-left-color: #02B7FB;
3174
+ position: relative; }
3175
+ .lp-notice.lp-upgrade-notice .close-notice,
3176
+ .learn-press-notice.lp-upgrade-notice .close-notice {
3177
+ position: absolute;
3178
+ top: 5px;
3179
+ right: 10px; }
3180
+ .lp-notice .lp-message-dismiss,
3181
+ .learn-press-notice .lp-message-dismiss {
3182
  position: absolute;
3183
+ right: 12px;
3184
+ top: 12px; }
3185
 
3186
  .learn-press-dropdown-pages {
3187
  display: inline-block; }
assets/js/admin/admin.js CHANGED
@@ -2,6 +2,40 @@
2
 
3
  "use strict";
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  function makePaymentsSortable() {
6
  // Make payments sortable
7
  $('.learn-press-payments.sortable tbody').sortable({
@@ -380,7 +414,7 @@
380
  });
381
  }
382
 
383
- function send_newsletter_info(e){
384
  var $notice = $(e.target),
385
  context = $notice.attr('data-context');
386
  $(this).addClass('updating-message button-working disabled');
@@ -403,7 +437,7 @@
403
  });
404
  }
405
 
406
- function checkUpdates(e){
407
  //e.preventDefault();
408
  }
409
 
@@ -433,7 +467,7 @@
433
  .on('click', '.learn-press-filter-template', _callbackFilterTemplates)
434
  .on('click', '.lp-duplicate-row-action .lp-duplicate-post', _duplicatePost)
435
  .on('click', '#learn-press-newsletter-button button', send_newsletter_info)
436
- .on('click','#learn-press-check-update-addons', checkUpdates)
437
  .on('mousedown', '.lp-sortable-handle', function (e) {
438
  $('html, body').addClass('lp-item-moving');
439
  $(e.target).closest('.lp-sortable-handle').css('cursor', 'inherit');
@@ -448,4 +482,3 @@
448
  $doc.ready(_ready);
449
  })(jQuery);
450
 
451
- if (typeof LP === 'undefined') LP = {};
2
 
3
  "use strict";
4
 
5
+ if (typeof LP === 'undefined') LP = {};
6
+
7
+ LP.dismissMessage = function (el, args) {
8
+ args = $.extend($(el).data(), args || {});
9
+
10
+ var dismissDone = function () {
11
+ if (args.el) {
12
+ $(args.el).fadeOut();
13
+ } else {
14
+ $(el).parent().fadeOut();
15
+ }
16
+ }
17
+
18
+ if (args.instant === 'yes') {
19
+ dismissDone();
20
+ }
21
+
22
+ $.ajax({
23
+ url: '',
24
+ data: {
25
+ 'lp-ajax': 'dismiss-notice',
26
+ name: args.name,
27
+ value: args.value || 'yes',
28
+ expired: args.expired || ''
29
+ },
30
+ type: 'POST',
31
+ success: function () {
32
+ if (args.instant !== 'yes') {
33
+ dismissDone();
34
+ }
35
+ }
36
+ })
37
+ }
38
+
39
  function makePaymentsSortable() {
40
  // Make payments sortable
41
  $('.learn-press-payments.sortable tbody').sortable({
414
  });
415
  }
416
 
417
+ function send_newsletter_info(e) {
418
  var $notice = $(e.target),
419
  context = $notice.attr('data-context');
420
  $(this).addClass('updating-message button-working disabled');
437
  });
438
  }
439
 
440
+ function checkUpdates(e) {
441
  //e.preventDefault();
442
  }
443
 
467
  .on('click', '.learn-press-filter-template', _callbackFilterTemplates)
468
  .on('click', '.lp-duplicate-row-action .lp-duplicate-post', _duplicatePost)
469
  .on('click', '#learn-press-newsletter-button button', send_newsletter_info)
470
+ .on('click', '#learn-press-check-update-addons', checkUpdates)
471
  .on('mousedown', '.lp-sortable-handle', function (e) {
472
  $('html, body').addClass('lp-item-moving');
473
  $(e.target).closest('.lp-sortable-handle').css('cursor', 'inherit');
482
  $doc.ready(_ready);
483
  })(jQuery);
484
 
 
assets/scss/admin/admin.scss CHANGED
@@ -26,6 +26,8 @@
26
 
27
  .lp-notice,
28
  .learn-press-notice {
 
 
29
  h4 {
30
  margin: 10px 0 15px
31
  }
@@ -43,6 +45,12 @@
43
  right: 10px;
44
  }
45
  }
 
 
 
 
 
 
46
  }
47
 
48
  .learn-press-dropdown-pages {
@@ -82,7 +90,7 @@
82
  }
83
  }
84
 
85
- .learn-press-notice-assigned-item{
86
  color: #FF0000;
87
  }
88
 
26
 
27
  .lp-notice,
28
  .learn-press-notice {
29
+ position: relative;
30
+ padding: 12px;
31
  h4 {
32
  margin: 10px 0 15px
33
  }
45
  right: 10px;
46
  }
47
  }
48
+
49
+ .lp-message-dismiss {
50
+ position: absolute;
51
+ right: 12px;
52
+ top: 12px;
53
+ }
54
  }
55
 
56
  .learn-press-dropdown-pages {
90
  }
91
  }
92
 
93
+ .learn-press-notice-assigned-item {
94
  color: #FF0000;
95
  }
96
 
inc/admin/class-lp-admin-ajax.php CHANGED
@@ -92,6 +92,7 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
92
  'skip-notice-install',
93
  'dashboard-order-status',
94
  'dashboard-plugin-status',
 
95
  'sync-course-orders',
96
  'sync-user-orders',
97
  'sync-course-final-quiz',
@@ -117,7 +118,7 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
117
  }
118
  }
119
 
120
- public function sync_calculate_course_results(){
121
  if ( empty( $_REQUEST['sync'] ) ) {
122
  die();
123
  }
@@ -142,7 +143,7 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
142
  learn_press_send_json( array( 'result' => 'success' ) );
143
 
144
  die();
145
- }
146
 
147
  /**
148
  * Sync orders for each course
@@ -225,8 +226,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
225
  }
226
 
227
  public function sync_remove_older_data() {
228
- $api = LP_Repair_Database::instance();
229
- $api->remove_older_post_meta();
230
  learn_press_send_json( array( 'result' => 'success' ) );
231
  die();
232
  }
@@ -486,7 +487,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
486
  if ( in_array( get_post_type( $id ), apply_filters( 'learn-press/reviewable-post-types', array(
487
  'lp_lesson',
488
  'lp_quiz'
489
- ) ) ) && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-item-preview' ) ) {
 
490
  $previewable = learn_press_get_request( 'previewable' );
491
  if ( is_null( $previewable ) ) {
492
  $previewable = '0';
@@ -675,7 +677,8 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
675
  if ( false === $data ) {
676
  try {
677
  $data = json_decode( file_get_contents( 'php://input' ), true );
678
- } catch ( Exception $exception ) {
 
679
  }
680
  }
681
  if ( $data && func_num_args() > 0 ) {
@@ -726,7 +729,7 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
726
  $term = stripslashes( $_REQUEST['term'] );
727
 
728
  if ( empty( $term ) ) {
729
- die(__FILE__ . '::'.__FUNCTION__);;
730
  }
731
 
732
  $found_customers = array();
@@ -771,18 +774,19 @@ if ( ! class_exists( 'LP_Admin_Ajax' ) ) {
771
  $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
772
  }
773
 
 
 
 
 
 
774
  public static function dismiss_notice() {
775
- $context = learn_press_get_request( 'context' );
776
- $transient = learn_press_get_request( 'transient' );
 
777
 
778
- if ( $context ) {
779
- if ( $transient >= 0 ) {
780
- set_transient( 'learn_press_dismiss_notice_' . $context, 'off', $transient ? $transient : DAY_IN_SECONDS * 7 );
781
- } else {
782
- update_option( 'learn_press_dismiss_notice_' . $context, 'off' );
783
- }
784
- }
785
- die(__FILE__ . '::'.__FUNCTION__);;
786
  }
787
 
788
  public static function plugin_action() {
92
  'skip-notice-install',
93
  'dashboard-order-status',
94
  'dashboard-plugin-status',
95
+ 'dismiss-notice',
96
  'sync-course-orders',
97
  'sync-user-orders',
98
  'sync-course-final-quiz',
118
  }
119
  }
120
 
121
+ public function sync_calculate_course_results() {
122
  if ( empty( $_REQUEST['sync'] ) ) {
123
  die();
124
  }
143
  learn_press_send_json( array( 'result' => 'success' ) );
144
 
145
  die();
146
+ }
147
 
148
  /**
149
  * Sync orders for each course
226
  }
227
 
228
  public function sync_remove_older_data() {
229
+ $api = LP_Repair_Database::instance();
230
+ $api->remove_older_post_meta();
231
  learn_press_send_json( array( 'result' => 'success' ) );
232
  die();
233
  }
487
  if ( in_array( get_post_type( $id ), apply_filters( 'learn-press/reviewable-post-types', array(
488
  'lp_lesson',
489
  'lp_quiz'
490
+ ) ) ) && wp_verify_nonce( learn_press_get_request( 'nonce' ), 'learn-press-toggle-item-preview' )
491
+ ) {
492
  $previewable = learn_press_get_request( 'previewable' );
493
  if ( is_null( $previewable ) ) {
494
  $previewable = '0';
677
  if ( false === $data ) {
678
  try {
679
  $data = json_decode( file_get_contents( 'php://input' ), true );
680
+ }
681
+ catch ( Exception $exception ) {
682
  }
683
  }
684
  if ( $data && func_num_args() > 0 ) {
729
  $term = stripslashes( $_REQUEST['term'] );
730
 
731
  if ( empty( $term ) ) {
732
+ die( __FILE__ . '::' . __FUNCTION__ );;
733
  }
734
 
735
  $found_customers = array();
774
  $query->query_where .= $wpdb->prepare( " OR user_name.meta_value LIKE %s ", '%' . $term . '%' );
775
  }
776
 
777
+ /**
778
+ * Dismiss notice
779
+ *
780
+ * @update 3.x.x
781
+ */
782
  public static function dismiss_notice() {
783
+ $name = learn_press_get_request( 'name' );
784
+ $value = learn_press_get_request( 'value' );
785
+ $expired = learn_press_get_request( 'expired' );
786
 
787
+ LP_Admin_Notice::instance()->dismiss_notice_2( $name, $value, $expired );
788
+
789
+ die();
 
 
 
 
 
790
  }
791
 
792
  public static function plugin_action() {
inc/admin/class-lp-admin-notice.php CHANGED
@@ -6,7 +6,7 @@
6
  * @author ThimPress
7
  * @version 1.0
8
  */
9
- if ( !defined( 'ABSPATH' ) ) {
10
  exit; // Exit if accessed directly
11
  }
12
 
@@ -20,17 +20,124 @@ class LP_Admin_Notice {
20
  */
21
  protected static $_notices = array();
22
 
 
 
 
 
 
 
 
23
  /**
24
  * LP_Admin_Notice construct
25
  */
26
- public function __construct() {
27
  add_action( 'init', array( $this, 'dismiss_notice' ) );
28
  add_action( 'admin_notices', array( __CLASS__, 'show_notices' ), 100000 );
29
  }
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  public function dismiss_notice() {
 
32
  $notice = learn_press_get_request( 'lp-hide-notice' );
33
- if ( !$notice ) {
34
  return;
35
  }
36
  if ( $transient = learn_press_get_request( 't' ) ) {
@@ -100,6 +207,21 @@ class LP_Admin_Notice {
100
  delete_transient( 'learn_press_redirect_notices' );
101
  }
102
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  }
104
 
105
- new LP_Admin_Notice();
6
  * @author ThimPress
7
  * @version 1.0
8
  */
9
+ if ( ! defined( 'ABSPATH' ) ) {
10
  exit; // Exit if accessed directly
11
  }
12
 
20
  */
21
  protected static $_notices = array();
22
 
23
+ /**
24
+ * @since 3.x.x
25
+ *
26
+ * @var LP_Admin_Notice
27
+ */
28
+ protected static $instance = false;
29
+
30
  /**
31
  * LP_Admin_Notice construct
32
  */
33
+ protected function __construct() {
34
  add_action( 'init', array( $this, 'dismiss_notice' ) );
35
  add_action( 'admin_notices', array( __CLASS__, 'show_notices' ), 100000 );
36
  }
37
 
38
+ /**
39
+ * Update option to turn-off a notice.
40
+ *
41
+ * @since 3.x.x
42
+ *
43
+ * @param string $name
44
+ * @param string $value
45
+ * @param int $expired
46
+ */
47
+ public function dismiss_notice_2( $name, $value, $expired = 0 ) {
48
+ if ( $expired ) {
49
+ set_transient( 'lp_dismiss_notice' . $name, $value, $expired );
50
+ } else {
51
+ $values = get_option( 'lp_dismiss_notice' );
52
+ if ( ! $values ) {
53
+ $values = array( $name => $value );
54
+ } else {
55
+ $values[ $name ] = $value;
56
+ }
57
+
58
+ update_option( 'lp_dismiss_notice', $values );
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Check if a notice has dismissed.
64
+ *
65
+ * @since 3.x.x
66
+ *
67
+ * @param string $name
68
+ *
69
+ * @return bool
70
+ */
71
+ public function has_dismissed_notice( $name ) {
72
+ if ( $transient = get_transient( 'lp_dismiss_notice' . $name ) ) {
73
+ return $transient;
74
+ }
75
+
76
+ $values = get_option( 'lp_dismiss_notice' );
77
+ if ( ! $values ) {
78
+ return false;
79
+ }
80
+
81
+ return isset( $values[ $name ] ) ? $values[ $name ] : false;
82
+ }
83
+
84
+ /**
85
+ * Remove a notice has been dismissed.
86
+ *
87
+ * @since 3.x.x
88
+ *
89
+ * @param string|array $name - Optional. NULL will remove all notices.
90
+ * @param bool $expired - Optional. TRUE if dismiss notice as transient (in case $name passed).
91
+ *
92
+ * @return bool
93
+ */
94
+ public function remove_dismissed_notice( $name = '' ) {
95
+
96
+ if ( ! $name ) {
97
+ global $wpdb;
98
+
99
+ $query = $wpdb->prepare( "SELECT SUBSTR(option_name, 12) FROM {$wpdb->options} WHERE option_name LIKE %s", '%' . $wpdb->esc_like( '_transient_lp_dismiss_notice' ) . '%' );
100
+
101
+ if ( $all_notices = $wpdb->get_col( $query ) ) {
102
+ foreach ( $all_notices as $notice ) {
103
+ delete_transient( $notice );
104
+ }
105
+ }
106
+
107
+ delete_option( 'lp_dismiss_notice' );
108
+
109
+ return true;
110
+ } elseif ( is_array( $name ) ) {
111
+ foreach ( $name as $notice ) {
112
+ $this->remove_dismissed_notice( $notice );
113
+ }
114
+
115
+ return true;
116
+ }
117
+
118
+ delete_transient( 'lp_dismiss_notice' . $name );
119
+
120
+ $values = get_option( 'lp_dismiss_notice' );
121
+
122
+ if ( ! $values ) {
123
+ return false;
124
+ } else {
125
+ if ( array_key_exists( $name, $values ) ) {
126
+ unset( $values[ $name ] );
127
+
128
+ update_option( 'lp_dismiss_notice', $values );
129
+
130
+ return $values;
131
+ }
132
+ }
133
+
134
+ return false;
135
+ }
136
+
137
  public function dismiss_notice() {
138
+
139
  $notice = learn_press_get_request( 'lp-hide-notice' );
140
+ if ( ! $notice ) {
141
  return;
142
  }
143
  if ( $transient = learn_press_get_request( 't' ) ) {
207
  delete_transient( 'learn_press_redirect_notices' );
208
  }
209
  }
210
+
211
+ /**
212
+ * Get single instance of this class
213
+ *
214
+ * @since 3.x.x
215
+ *
216
+ * @return LP_Admin_Notice
217
+ */
218
+ public static function instance() {
219
+ if ( ! self::$instance ) {
220
+ self::$instance = new self();
221
+ }
222
+
223
+ return self::$instance;
224
+ }
225
  }
226
 
227
+ LP_Admin_Notice::instance();
inc/admin/class-lp-post-type-actions.php CHANGED
@@ -28,7 +28,7 @@ class LP_Post_Type_Actions {
28
  add_filter( 'pre_trash_post', array( $this, 'pre_trash_post' ), 10, 2 );
29
  add_filter( 'trashed_post', array( $this, 'trashed_post' ), 1000, 1 );
30
 
31
- add_filter( 'before_delete_post', array( $this, 'before_delete_post' ), 1000, 1 );
32
  //add_filter( 'deleted_post', array( $this, 'deleted_post' ), 1000, 1 );
33
 
34
  add_filter( 'transition_post_status', array( $this, 'transition_post_status' ), 1000, 3 );
28
  add_filter( 'pre_trash_post', array( $this, 'pre_trash_post' ), 10, 2 );
29
  add_filter( 'trashed_post', array( $this, 'trashed_post' ), 1000, 1 );
30
 
31
+ // add_filter( 'before_delete_post', array( $this, 'before_delete_post' ), 1000, 1 );
32
  //add_filter( 'deleted_post', array( $this, 'deleted_post' ), 1000, 1 );
33
 
34
  add_filter( 'transition_post_status', array( $this, 'transition_post_status' ), 1000, 3 );
inc/admin/views/html-admin-notice-templates.php CHANGED
@@ -4,7 +4,7 @@ if ( ! defined( 'ABSPATH' ) ) {
4
  exit;
5
  }
6
 
7
- if ( learn_press_get_user_option( 'hide-notice-template-files' ) == 'yes' ) {
8
  return;
9
  }
10
  $template_dir = get_template_directory();
@@ -27,7 +27,7 @@ $theme_name = implode( ' & ', $theme_name );
27
 
28
  $readmore = 'https://thimpress.com/knowledge-base/outdated-template-fix/';
29
  ?>
30
- <div id="message" class="learn-press-message notice-warning notice">
31
  <p><?php printf( wp_kses( __( 'There is a new update of LearnPress. You may need to update your theme <strong>(%s)</strong> to avoid outdated template files.', 'learnpress' ), array( 'strong' => array() ) ), $theme_name ); ?></p>
32
  <p class="outdated-readmore-link"><?php echo sprintf( wp_kses( __( 'This is not a bug, don\'t worry. Read more about Outdated template files notice <a href="%s" target="_blank">here</a>.', 'learnpress' ), array(
33
  'a' => array(
@@ -38,7 +38,13 @@ $readmore = 'https://thimpress.com/knowledge-base/outdated-template-fix/';
38
  <p>
39
  <a class="button"
40
  href="<?php echo admin_url( 'admin.php?page=learn-press-tools&amp;tab=templates' ); ?>"><?php esc_attr_e( 'View list of outdated templates', 'learnpress' ); ?></a>
 
 
 
 
 
 
 
41
  </p>
42
- <a href="<?php echo admin_url( 'themes.php/?lp-hide-notice=template-files' ); ?>"
43
- class="learn-press-admin-notice-dismiss"></a>
44
  </div>
4
  exit;
5
  }
6
 
7
+ if ( LP_Admin_Notice::instance()->has_dismissed_notice( 'outdated-template' ) == 'yes' ) {
8
  return;
9
  }
10
  $template_dir = get_template_directory();
27
 
28
  $readmore = 'https://thimpress.com/knowledge-base/outdated-template-fix/';
29
  ?>
30
+ <div id="message" class="learn-press-notice notice-warning notice">
31
  <p><?php printf( wp_kses( __( 'There is a new update of LearnPress. You may need to update your theme <strong>(%s)</strong> to avoid outdated template files.', 'learnpress' ), array( 'strong' => array() ) ), $theme_name ); ?></p>
32
  <p class="outdated-readmore-link"><?php echo sprintf( wp_kses( __( 'This is not a bug, don\'t worry. Read more about Outdated template files notice <a href="%s" target="_blank">here</a>.', 'learnpress' ), array(
33
  'a' => array(
38
  <p>
39
  <a class="button"
40
  href="<?php echo admin_url( 'admin.php?page=learn-press-tools&amp;tab=templates' ); ?>"><?php esc_attr_e( 'View list of outdated templates', 'learnpress' ); ?></a>
41
+
42
+ <a href=""
43
+ onclick="LP.dismissMessage(this, {expired: 3600}); return false;"
44
+ data-name="outdated-template"
45
+ data-value="yes"
46
+ data-el="#message"
47
+ data-instant="yes"><?php esc_html_e( 'Dismiss', 'learnpress' ); ?></a>
48
  </p>
49
+
 
50
  </div>
inc/class-lp-install.php CHANGED
@@ -170,6 +170,12 @@ if ( ! function_exists( 'LP_Install' ) ) {
170
  // Force to show notice outdated template
171
  learn_press_delete_user_option( 'hide-notice-template-files' );
172
 
 
 
 
 
 
 
173
  self::update_db_version();
174
  self::update_version();
175
  }
170
  // Force to show notice outdated template
171
  learn_press_delete_user_option( 'hide-notice-template-files' );
172
 
173
+ LP_Admin_Notice::instance()->remove_dismissed_notice(
174
+ array(
175
+ 'outdated-template'
176
+ )
177
+ );
178
+
179
  self::update_db_version();
180
  self::update_version();
181
  }
inc/class-lp-market-products.php CHANGED
@@ -1,40 +1,40 @@
1
  <?php
2
-
3
- class LP_Market_Products {
4
- public function __construct() {
5
-
6
- add_filter( 'tpl-market-products', array( $this, 'market_products' ) );
7
-
8
- }
9
-
10
- public function market_products( $products = array() ) {
11
- $products['learnpress'] = array(
12
- 'name' => __( 'LearnPress', 'learnpress' ),
13
- 'desc' => __( 'Ahihi', 'learnpress' ),
14
- 'priority' => 5,
15
- 'items' => array(
16
- array(
17
- 'name' => 'LearnPress Course Review',
18
- 'slug' => 'learnpress-course-review',
19
- 'required' => false,
20
- 'version' => '2.0',
21
- 'description' => 'Adding review for course By ThimPress.',
22
- 'add-on' => true,
23
- ),
24
- array(
25
- 'name' => 'LearnPress Gradebook',
26
- 'slug' => 'learnpress-gradebook',
27
- 'required' => false,
28
- 'version' => '2.0',
29
- 'premium' => true,
30
- 'description' => 'Adding review for course By ThimPress.',
31
- 'add-on' => true,
32
- ),
33
- )
34
- );
35
-
36
- return $products;
37
- }
38
- }
39
-
40
- return new LP_Market_Products();
1
  <?php
2
+ //
3
+ //class LP_Market_Products {
4
+ // public function __construct() {
5
+ //
6
+ // add_filter( 'tpl-market-products', array( $this, 'market_products' ) );
7
+ //
8
+ // }
9
+ //
10
+ // public function market_products( $products = array() ) {
11
+ // $products['learnpress'] = array(
12
+ // 'name' => __( 'LearnPress', 'learnpress' ),
13
+ // 'desc' => __( 'Ahihi', 'learnpress' ),
14
+ // 'priority' => 5,
15
+ // 'items' => array(
16
+ // array(
17
+ // 'name' => 'LearnPress Course Review',
18
+ // 'slug' => 'learnpress-course-review',
19
+ // 'required' => false,
20
+ // 'version' => '2.0',
21
+ // 'description' => 'Adding review for course By ThimPress.',
22
+ // 'add-on' => true,
23
+ // ),
24
+ // array(
25
+ // 'name' => 'LearnPress Gradebook',
26
+ // 'slug' => 'learnpress-gradebook',
27
+ // 'required' => false,
28
+ // 'version' => '2.0',
29
+ // 'premium' => true,
30
+ // 'description' => 'Adding review for course By ThimPress.',
31
+ // 'add-on' => true,
32
+ // ),
33
+ // )
34
+ // );
35
+ //
36
+ // return $products;
37
+ // }
38
+ //}
39
+ //
40
+ //return new LP_Market_Products();
inc/class-lp-repair-database.php CHANGED
@@ -687,7 +687,7 @@ class LP_Repair_Database {
687
  $courses_format = array_fill( 0, sizeof( $courses ), '%d' );
688
  $statuses_format = $wpdb->prepare( join( ',', $statuses_format ), $statuses );
689
  $courses_format = $wpdb->prepare( join( ',', $courses_format ), $courses );
690
-
691
  $query = $wpdb->prepare( "
692
  SELECT cid, status, orders
693
  FROM(
687
  $courses_format = array_fill( 0, sizeof( $courses ), '%d' );
688
  $statuses_format = $wpdb->prepare( join( ',', $statuses_format ), $statuses );
689
  $courses_format = $wpdb->prepare( join( ',', $courses_format ), $courses );
690
+ $wpdb->query( 'SET SESSION group_concat_max_len = 18446744073709551615' );
691
  $query = $wpdb->prepare( "
692
  SELECT cid, status, orders
693
  FROM(
inc/curds/class-lp-course-curd.php CHANGED
@@ -417,18 +417,21 @@ if ( ! class_exists( 'LP_Course_CURD' ) ) {
417
 
418
  public function get_course_items( $course_id, $section_ids = array() ) {
419
  global $wpdb;
 
420
  $query = $wpdb->prepare( "
421
  SELECT section_items.item_id
422
  FROM {$wpdb->posts} course
423
  INNER JOIN {$wpdb->learnpress_sections} course_sections ON course.ID = course_sections.section_course_id
424
  INNER JOIN {$wpdb->learnpress_section_items} section_items ON course_sections.section_id = section_items.section_id
 
425
  WHERE course.ID = %d
 
426
  ", $course_id );
427
 
428
  if ( $section_ids ) {
429
  $query .= " AND course_sections.section_id IN(" . join( ',', $section_ids ) . ")";
430
  }
431
-
432
  return $wpdb->get_col( $query );
433
  }
434
 
417
 
418
  public function get_course_items( $course_id, $section_ids = array() ) {
419
  global $wpdb;
420
+ $type = learn_press_course_get_support_item_types( true );
421
  $query = $wpdb->prepare( "
422
  SELECT section_items.item_id
423
  FROM {$wpdb->posts} course
424
  INNER JOIN {$wpdb->learnpress_sections} course_sections ON course.ID = course_sections.section_course_id
425
  INNER JOIN {$wpdb->learnpress_section_items} section_items ON course_sections.section_id = section_items.section_id
426
+ INNER JOIN {$wpdb->posts} p ON p.ID = section_items.item_id
427
  WHERE course.ID = %d
428
+ AND section_items.item_type IN('" . join( "','", $type ) . "')
429
  ", $course_id );
430
 
431
  if ( $section_ids ) {
432
  $query .= " AND course_sections.section_id IN(" . join( ',', $section_ids ) . ")";
433
  }
434
+ $query .= " ORDER BY course_sections.section_order, section_items.item_order";
435
  return $wpdb->get_col( $query );
436
  }
437
 
inc/custom-post-types/order.php CHANGED
@@ -485,19 +485,20 @@ if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
485
  */
486
  public function posts_where_paged( $where ) {
487
  global $wpdb, $wp_query;
 
 
 
 
 
 
 
 
 
 
 
 
488
 
489
  if ( ! $this->_is_archive() || ! $this->_is_search() ) {
490
- if(is_admin() && !$wp_query->query['post_status']){
491
- $statuses = array_keys(learn_press_get_register_order_statuses());
492
- $search = "{$wpdb->posts}.post_status = 'publish' ";
493
- $tmps = array($search);
494
- $tmp = "{$wpdb->posts}.post_status = %s ";
495
- foreach($statuses as $status ){
496
- $tmps[]=$wpdb->prepare( $tmp, $status );
497
- }
498
- $replace = implode(' OR ',$tmps);
499
- $where = str_replace($search, $replace, $where);
500
- }
501
  return $where;
502
  }
503
 
@@ -546,6 +547,10 @@ if ( ! class_exists( 'LP_Order_Post_Type' ) ) {
546
  OR {$wpdb->posts}.ID LIKE %s
547
  ) ";
548
  $sql = $wpdb->prepare( $sql, array( LP_ORDER_CPT, '_user_id', $s, $s, $s, $s, $s ) );
 
 
 
 
549
  if ( ! empty( $matches2 ) && isset( $matches2[0] ) ) {
550
  $where = str_replace( $matches2[0], $sql . ' OR ' . $matches2[0], $where );
551
  } else {
485
  */
486
  public function posts_where_paged( $where ) {
487
  global $wpdb, $wp_query;
488
+
489
+ if(is_admin() && $this->_is_archive() && !$wp_query->query['post_status']){
490
+ $statuses = array_keys(learn_press_get_register_order_statuses());
491
+ $search = "{$wpdb->posts}.post_status = 'publish' ";
492
+ $tmps = array($search);
493
+ $tmp = "{$wpdb->posts}.post_status = %s ";
494
+ foreach($statuses as $status ){
495
+ $tmps[]=$wpdb->prepare( $tmp, $status );
496
+ }
497
+ $replace = implode(' OR ',$tmps);
498
+ $where = str_replace($search, $replace, $where);
499
+ }
500
 
501
  if ( ! $this->_is_archive() || ! $this->_is_search() ) {
 
 
 
 
 
 
 
 
 
 
 
502
  return $where;
503
  }
504
 
547
  OR {$wpdb->posts}.ID LIKE %s
548
  ) ";
549
  $sql = $wpdb->prepare( $sql, array( LP_ORDER_CPT, '_user_id', $s, $s, $s, $s, $s ) );
550
+ # search order via course name
551
+ $sql .= " OR ".$wpdb->prepare( " {$wpdb->posts}.ID IN (
552
+ SELECT DISTINCT order_id FROM {$wpdb->learnpress_order_items} WHERE `order_item_name` like %s
553
+ )",$s);
554
  if ( ! empty( $matches2 ) && isset( $matches2[0] ) ) {
555
  $where = str_replace( $matches2[0], $sql . ' OR ' . $matches2[0], $where );
556
  } else {
inc/lp-constants.php CHANGED
@@ -4,7 +4,7 @@
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
- define( 'LEARNPRESS_VERSION', '3.2.4' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
4
  */
5
  $upload_dir = wp_upload_dir();
6
  // version
7
+ define( 'LEARNPRESS_VERSION', '3.2.5' );
8
 
9
  define( 'LP_WP_CONTENT', basename( WP_CONTENT_DIR ) );
10
 
inc/lp-core-functions.php CHANGED
@@ -554,7 +554,7 @@ function learn_press_setup_pages() {
554
  wp_cache_add( $page->ID, $page, 'posts' );
555
  }
556
 
557
- LP_Object_Cache::set( 'static-page-ids', $page_ids, 'learn-press' );
558
  }
559
  }
560
 
554
  wp_cache_add( $page->ID, $page, 'posts' );
555
  }
556
 
557
+ //LP_Object_Cache::set( 'static-page-ids', $page_ids, 'learn-press' );
558
  }
559
  }
560
 
inc/user-item/class-lp-user-item-course.php CHANGED
@@ -219,7 +219,7 @@ class LP_User_Item_Course extends LP_User_Item implements ArrayAccess {
219
  public function offsetExists( $offset ) {
220
  $items = $this->read_items();
221
 
222
- return array_key_exists( $offset, $items );
223
  }
224
 
225
  public function evaluate() {
219
  public function offsetExists( $offset ) {
220
  $items = $this->read_items();
221
 
222
+ return array_key_exists( $offset, (array) $items );
223
  }
224
 
225
  public function evaluate() {
inc/user-item/class-lp-user-item.php CHANGED
@@ -264,7 +264,19 @@ class LP_User_Item extends LP_Abstract_Object_Data implements ArrayAccess {
264
  * @return string
265
  */
266
  public function get_status() {
267
- return $this->get_data( 'status' );
 
 
 
 
 
 
 
 
 
 
 
 
268
  }
269
 
270
  public function is_exists() {
264
  * @return string
265
  */
266
  public function get_status() {
267
+ $got_status = $this->get_data( 'status' );
268
+ if ( ! $got_status && false !== ( $user_id = $this->get_extra_data( 'user_id' ) ) ) {
269
+ $user_item = learn_press_get_user_item( array(
270
+ 'user_id' => $user_id,
271
+ 'item_id' => $this->get_item_id(),
272
+ 'parent_id' => $this->get_parent_id(),
273
+ 'ref_id' => $this->get_data( 'ref_id' )
274
+ ) );
275
+ if ( ! empty( $user_item ) ) {
276
+ $got_status = $user_item->status;
277
+ }
278
+ }
279
+ return $got_status;
280
  }
281
 
282
  public function is_exists() {
inc/user/abstract-lp-user.php CHANGED
@@ -60,7 +60,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
60
  /**
61
  * LP_Abstract_User constructor.
62
  *
63
- * @param int $the_user
64
  * @param array $args
65
  */
66
  public function __construct( $the_user = 0, $args = array() ) {
@@ -96,7 +96,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
96
  * @updated 3.1.0
97
  *
98
  * @param int|LP_Abstract_Course $course_id
99
- * @param bool $check_exists
100
  *
101
  * @return LP_User_Item_Course|LP_User_Item_Quiz|bool
102
  */
@@ -214,7 +214,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
214
  * Check if a course is exists then return it's ID.
215
  * Try to get it from global.
216
  *
217
- * @param int $course_id
218
  * @param string $return
219
  *
220
  * @return bool|false|int|LP_Course
@@ -260,8 +260,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
260
  * Return TRUE if an item has a status.
261
  *
262
  * @param array $statuses
263
- * @param int $item_id
264
- * @param int $course_id
265
  *
266
  * @return mixed
267
  *
@@ -277,8 +277,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
277
  /**
278
  * Get all records of an item.
279
  *
280
- * @param int $item_id
281
- * @param int $course_id
282
  * @param bool $return_last
283
  *
284
  * @return bool|mixed
@@ -318,8 +318,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
318
  /**
319
  * Start quiz for the user.
320
  *
321
- * @param int $quiz_id
322
- * @param int $course_id
323
  * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
324
  *
325
  * @throws Exception
@@ -337,7 +337,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
337
  if ( false === ( $course_id = $this->_verify_course_item( $quiz_id, $course_id ) ) ) {
338
  throw new Exception( __( 'Course does not exist or does not contain the quiz', 'learnpress' ), LP_INVALID_QUIZ_OR_COURSE );
339
  }
340
- $course = learn_press_get_course( $course_id );
341
  $access_level = $this->get_course_access_level( $course_id );
342
 
343
  // If user has already finished the course
@@ -353,7 +353,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
353
  if ( $this->has_item_status( array( 'started', 'completed' ), $quiz_id, $course_id ) ) {
354
  throw new Exception( __( 'User has started or completed quiz', 'learnpress' ), LP_QUIZ_HAS_STARTED_OR_COMPLETED );
355
  }
356
- $user = LP_Global::user();
357
 
358
  if ( $course->is_required_enroll() && $user->is_guest()/* && ! $quiz->get_preview() */ ) {
359
  throw new Exception( __( 'You have to login for starting quiz.', 'learnpress' ), LP_REQUIRE_LOGIN );
@@ -374,6 +374,23 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
374
  $course_data = $this->get_course_data( $course_id );
375
  $quiz = learn_press_get_quiz( $quiz_id );
376
  $quiz_data = $course_data->get_item( $quiz_id );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
377
 
378
  if ( ! $enable_history = $quiz->enable_archive_history() ) {
379
  if ( $quiz_data->get_user_item_id() ) {
@@ -393,6 +410,10 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
393
 
394
  $course_data->update_item_retaken_count( $quiz_id, '+1' );
395
  $quiz_data->set_status( 'started' );
 
 
 
 
396
 
397
  if ( $quiz_data->update() ) {
398
  $course_data->set_item( $quiz_data );
@@ -412,8 +433,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
412
  do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
413
 
414
  $return = $quiz_data->get_mysql_data();
415
- }
416
- catch ( Exception $ex ) {
417
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
418
  }
419
 
@@ -423,8 +443,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
423
  /**
424
  * Finish a quiz for the user and save all data needed
425
  *
426
- * @param int $quiz_id
427
- * @param int $course_id
428
  * @param bool $wp_error
429
  *
430
  * @return mixed
@@ -473,8 +493,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
473
  /**
474
  * Retake a quiz for the user
475
  *
476
- * @param int $quiz_id
477
- * @param int $course_id
478
  * @param bool $wp_error
479
  *
480
  * @return bool|WP_Error
@@ -486,6 +506,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
486
  if ( ! apply_filters( 'learn-press/user/before-retake-quiz', true, $quiz_id, $course_id, $this->get_id() ) ) {
487
  return false;
488
  }
 
489
  $return = false;
490
  try {
491
 
@@ -510,13 +531,18 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
510
  $quiz_data = $course_data->get_item( $quiz_id );
511
 
512
  if ( ! $enable_history = $quiz->enable_archive_history() ) {
513
- if ( $quiz_data->get_user_item_id() ) {
514
  global $wpdb;
515
- $query = $wpdb->prepare( "
516
- DELETE FROM {$wpdb->learnpress_user_items}
517
- WHERE user_id = %d AND item_id = %d AND user_item_id <> %d
518
- ", $this->get_id(), $quiz_id, $quiz_data->get_user_item_id() );
 
519
 
 
 
 
 
520
  $wpdb->query( $query );
521
  } else {
522
  $course_data->update_item_retaken_count( $quiz_id, 0 );
@@ -662,8 +688,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
662
  }
663
 
664
  /**
665
- * @param int $item_id
666
- * @param int $course_id
667
  * @param bool $last
668
  *
669
  * @since 3.0.0
@@ -720,8 +746,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
720
  /**
721
  * Get current status of an item for user.
722
  *
723
- * @param int $item_id
724
- * @param int $course_id
725
  * @param bool $force
726
  *
727
  * @return bool|mixed
@@ -769,7 +795,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
769
  //learn_press_show_log($course_data, $course_data->get_item( $item_id ));
770
 
771
  if ( $item = $course_data->get_item( $item_id ) ) {
772
- learn_press_show_log('HERE');
773
  } else {
774
  $item = LP_User_Item::get_item_object( $item_id );
775
  $item->set_ref_id( $course_id );
@@ -829,8 +855,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
829
  /**
830
  * Get current question's ID/Permalink inside quiz.
831
  *
832
- * @param int $quiz_id
833
- * @param int $course_id
834
  * @param bool $permalink
835
  *
836
  * @return bool|int|string
@@ -846,10 +872,13 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
846
  return false;
847
  }
848
 
849
- $quiz = learn_press_get_quiz( $quiz_id );
850
- $quiz_item = $data[ $quiz_id ];
851
- $question_id = $quiz_item->get_current_question();
852
-
 
 
 
853
  if ( $question_id && $permalink ) {
854
  return apply_filters( 'learn-press/current-user-question-permalink', $quiz->get_question_link( $question_id ), $quiz_id, $course_id, $this->get_id() );
855
  }
@@ -890,9 +919,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
890
  * Checks if has status of a quiz for user
891
  *
892
  * @param string|array $statuses
893
- * @param int $quiz_id
894
- * @param int $course_id
895
- * @param boolean $force
896
  *
897
  * @return bool
898
  */
@@ -908,8 +937,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
908
  /**
909
  * Get current results of a quiz
910
  *
911
- * @param int $quiz_id
912
- * @param int $course_id
913
  * @param string $prop
914
  *
915
  * @return mixed
@@ -1064,9 +1093,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1064
  /**
1065
  * Get history of a quiz for an user
1066
  *
1067
- * @param int $quiz_id
1068
- * @param int $course_id
1069
- * @param int $history_id
1070
  * @param bool $force
1071
  *
1072
  * @return mixed|null|void
@@ -1312,7 +1341,9 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1312
 
1313
  $view = false;
1314
  $course = learn_press_get_course( $course_id );
1315
-
 
 
1316
  // Disable preview course when course status is pending
1317
  if ( $course && $course->is_publish() && ( $item = $course->get_item( $item_id ) ) ) {
1318
  if ( $this->has_course_access_level( array(
@@ -1546,7 +1577,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1546
  * - started: value of column `status` in user_items is started
1547
  * - enrolled: value of column `status` in user_items is enrolled
1548
  *
1549
- * @param int $course_id
1550
  * @param string|array $statuses
1551
  *
1552
  * @since 2.0
@@ -1718,7 +1749,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1718
  /**
1719
  * Return true if user has already enrolled course
1720
  *
1721
- * @param int $course_id
1722
  * @param bool $force
1723
  *
1724
  * @return bool
@@ -1845,7 +1876,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1845
  /**
1846
  * Count number of time user has retaken a quiz
1847
  *
1848
- * @param int $course_id
1849
  * @param bool $force
1850
  *
1851
  * @return int
@@ -1961,8 +1992,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
1961
  do_action( 'learn_press_user_complete_lesson', $lesson_id, $result, $this->get_id() );
1962
 
1963
  do_action( 'learn-press/user-completed-lesson', $lesson_id, $course_id, $this->get_id() );
1964
- }
1965
- catch ( Exception $ex ) {
1966
  $result = $return_wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
1967
  }
1968
 
@@ -2157,8 +2187,8 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2157
  *
2158
  * @since 3.1.0
2159
  *
2160
- * @param int[] $access_level
2161
- * @param int $course_id
2162
  * @param string $compare
2163
  *
2164
  * @return bool
@@ -2369,7 +2399,7 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2369
  global $wpdb;
2370
 
2371
  $course = learn_press_get_course( $course_id );
2372
- $user_id = get_current_user_id();
2373
 
2374
  if ( $course->is_required_enroll() && ! $force ) {
2375
 
@@ -2388,7 +2418,11 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2388
  }
2389
 
2390
  $user_item_api = new LP_User_Item_CURD();
2391
- $course_item = $user_item_api->get_item_by( array( 'item_id' => $course_id, 'ref_id' => $order_id ) );
 
 
 
 
2392
 
2393
  if ( ! $course_item ) {
2394
  $course_item = LP_User_Item::get_empty_item();
@@ -2401,13 +2435,16 @@ if ( ! class_exists( 'LP_Abstract_User' ) ) {
2401
  $course_item['item_id'] = $course_id;
2402
  $course_item['item_type'] = learn_press_get_post_type( $course_id );
2403
  $course_item['ref_id'] = $order_id;
2404
- $course_item['ref_type'] = learn_press_get_post_type( $order_id );
2405
  $course_item['start_time'] = $date->toSql();
2406
  $course_item['start_time_gmt'] = $date->toSql( false );
2407
 
2408
  $user_course = new LP_User_Item_Course( $course_item );
2409
  $user_course->set_status( 'enrolled' );
2410
- $user_course->update();
 
 
 
2411
 
2412
  learn_press_remove_message( '', 'error' );
2413
  $user_id = is_user_logged_in() ? $this->get_id() : 0;
60
  /**
61
  * LP_Abstract_User constructor.
62
  *
63
+ * @param int $the_user
64
  * @param array $args
65
  */
66
  public function __construct( $the_user = 0, $args = array() ) {
96
  * @updated 3.1.0
97
  *
98
  * @param int|LP_Abstract_Course $course_id
99
+ * @param bool $check_exists
100
  *
101
  * @return LP_User_Item_Course|LP_User_Item_Quiz|bool
102
  */
214
  * Check if a course is exists then return it's ID.
215
  * Try to get it from global.
216
  *
217
+ * @param int $course_id
218
  * @param string $return
219
  *
220
  * @return bool|false|int|LP_Course
260
  * Return TRUE if an item has a status.
261
  *
262
  * @param array $statuses
263
+ * @param int $item_id
264
+ * @param int $course_id
265
  *
266
  * @return mixed
267
  *
277
  /**
278
  * Get all records of an item.
279
  *
280
+ * @param int $item_id
281
+ * @param int $course_id
282
  * @param bool $return_last
283
  *
284
  * @return bool|mixed
318
  /**
319
  * Start quiz for the user.
320
  *
321
+ * @param int $quiz_id
322
+ * @param int $course_id
323
  * @param bool $wp_error Optional. Whether to return a WP_Error on failure. Default false.
324
  *
325
  * @throws Exception
337
  if ( false === ( $course_id = $this->_verify_course_item( $quiz_id, $course_id ) ) ) {
338
  throw new Exception( __( 'Course does not exist or does not contain the quiz', 'learnpress' ), LP_INVALID_QUIZ_OR_COURSE );
339
  }
340
+ $course = learn_press_get_course( $course_id );
341
  $access_level = $this->get_course_access_level( $course_id );
342
 
343
  // If user has already finished the course
353
  if ( $this->has_item_status( array( 'started', 'completed' ), $quiz_id, $course_id ) ) {
354
  throw new Exception( __( 'User has started or completed quiz', 'learnpress' ), LP_QUIZ_HAS_STARTED_OR_COMPLETED );
355
  }
356
+ $user = LP_Global::user();
357
 
358
  if ( $course->is_required_enroll() && $user->is_guest()/* && ! $quiz->get_preview() */ ) {
359
  throw new Exception( __( 'You have to login for starting quiz.', 'learnpress' ), LP_REQUIRE_LOGIN );
374
  $course_data = $this->get_course_data( $course_id );
375
  $quiz = learn_press_get_quiz( $quiz_id );
376
  $quiz_data = $course_data->get_item( $quiz_id );
377
+ if ( ! $quiz_data ) {
378
+ $user_item_api = new LP_User_Item_CURD();
379
+ $course_item = $user_item_api->get_item_by( array(
380
+ 'item_id' => $course_id,
381
+ 'user_id' => $user->get_id()
382
+ ) );
383
+
384
+ $quiz_item = LP_User_Item::get_empty_item();
385
+ $quiz_item['user_id'] = $user->get_id();
386
+ $quiz_item['item_id'] = $quiz_id;
387
+ $quiz_item['item_type'] = learn_press_get_post_type( $quiz_id );
388
+ $quiz_item['ref_id'] = $course_id;
389
+ $quiz_item['ref_type'] = learn_press_get_post_type( $course_id );
390
+ $quiz_item['parent_id'] = $course_item->user_item_id;
391
+
392
+ $quiz_data = new LP_User_Item_Quiz( $quiz_item );
393
+ }
394
 
395
  if ( ! $enable_history = $quiz->enable_archive_history() ) {
396
  if ( $quiz_data->get_user_item_id() ) {
410
 
411
  $course_data->update_item_retaken_count( $quiz_id, '+1' );
412
  $quiz_data->set_status( 'started' );
413
+ $quiz_data->set_user_id( $user->get_id() );
414
+ $date = new LP_Datetime();
415
+ $quiz_data->set_start_time( $date->toSql() );
416
+ $quiz_data->set_end_time_gmt( $date->toSql( false ) );
417
 
418
  if ( $quiz_data->update() ) {
419
  $course_data->set_item( $quiz_data );
433
  do_action( 'learn-press/user/quiz-started', $quiz_id, $course_id, $this->get_id() );
434
 
435
  $return = $quiz_data->get_mysql_data();
436
+ } catch ( Exception $ex ) {
 
437
  $return = $wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
438
  }
439
 
443
  /**
444
  * Finish a quiz for the user and save all data needed
445
  *
446
+ * @param int $quiz_id
447
+ * @param int $course_id
448
  * @param bool $wp_error
449
  *
450
  * @return mixed
493
  /**
494
  * Retake a quiz for the user
495
  *
496
+ * @param int $quiz_id
497
+ * @param int $course_id
498
  * @param bool $wp_error
499
  *
500
  * @return bool|WP_Error
506
  if ( ! apply_filters( 'learn-press/user/before-retake-quiz', true, $quiz_id, $course_id, $this->get_id() ) ) {
507
  return false;
508
  }
509
+
510
  $return = false;
511
  try {
512
 
531
  $quiz_data = $course_data->get_item( $quiz_id );
532
 
533
  if ( ! $enable_history = $quiz->enable_archive_history() ) {
534
+ if ( $user_item_id = $quiz_data->get_user_item_id() ) {
535
  global $wpdb;
536
+ $query_meta = $wpdb->prepare( "
537
+ DELETE FROM {$wpdb->learnpress_user_itemmeta}
538
+ WHERE learnpress_user_item_id = %d
539
+ ", $user_item_id );
540
+ $wpdb->query( $query_meta );
541
 
542
+ $query = $wpdb->prepare( "
543
+ DELETE FROM {$wpdb->learnpress_user_items}
544
+ WHERE user_id = %d AND item_id = %d AND user_item_id <> %d
545
+ ", $this->get_id(), $quiz_id, $quiz_data->get_user_item_id() );
546
  $wpdb->query( $query );
547
  } else {
548
  $course_data->update_item_retaken_count( $quiz_id, 0 );
688
  }
689
 
690
  /**
691
+ * @param int $item_id
692
+ * @param int $course_id
693
  * @param bool $last
694
  *
695
  * @since 3.0.0
746
  /**
747
  * Get current status of an item for user.
748
  *
749
+ * @param int $item_id
750
+ * @param int $course_id
751
  * @param bool $force
752
  *
753
  * @return bool|mixed
795
  //learn_press_show_log($course_data, $course_data->get_item( $item_id ));
796
 
797
  if ( $item = $course_data->get_item( $item_id ) ) {
798
+ learn_press_show_log( 'HERE' );
799
  } else {
800
  $item = LP_User_Item::get_item_object( $item_id );
801
  $item->set_ref_id( $course_id );
855
  /**
856
  * Get current question's ID/Permalink inside quiz.
857
  *
858
+ * @param int $quiz_id
859
+ * @param int $course_id
860
  * @param bool $permalink
861
  *
862
  * @return bool|int|string
872
  return false;
873
  }
874
 
875
+ $quiz = learn_press_get_quiz( $quiz_id );
876
+ $quiz_item = $data[ $quiz_id ];
877
+ $question_id = $quiz_item->get_current_question();
878
+ $viewing_question = $quiz->get_viewing_question( 'id' );
879
+ if ( $viewing_question && $question_id != $viewing_question ) {
880
+ $question_id = $viewing_question;
881
+ }
882
  if ( $question_id && $permalink ) {
883
  return apply_filters( 'learn-press/current-user-question-permalink', $quiz->get_question_link( $question_id ), $quiz_id, $course_id, $this->get_id() );
884
  }
919
  * Checks if has status of a quiz for user
920
  *
921
  * @param string|array $statuses
922
+ * @param int $quiz_id
923
+ * @param int $course_id
924
+ * @param boolean $force
925
  *
926
  * @return bool
927
  */
937
  /**
938
  * Get current results of a quiz
939
  *
940
+ * @param int $quiz_id
941
+ * @param int $course_id
942
  * @param string $prop
943
  *
944
  * @return mixed
1093
  /**
1094
  * Get history of a quiz for an user
1095
  *
1096
+ * @param int $quiz_id
1097
+ * @param int $course_id
1098
+ * @param int $history_id
1099
  * @param bool $force
1100
  *
1101
  * @return mixed|null|void
1341
 
1342
  $view = false;
1343
  $course = learn_press_get_course( $course_id );
1344
+ if ( ! $course_id ) {
1345
+ $course_id = $course->get_id();
1346
+ }
1347
  // Disable preview course when course status is pending
1348
  if ( $course && $course->is_publish() && ( $item = $course->get_item( $item_id ) ) ) {
1349
  if ( $this->has_course_access_level( array(
1577
  * - started: value of column `status` in user_items is started
1578
  * - enrolled: value of column `status` in user_items is enrolled
1579
  *
1580
+ * @param int $course_id
1581
  * @param string|array $statuses
1582
  *
1583
  * @since 2.0
1749
  /**
1750
  * Return true if user has already enrolled course
1751
  *
1752
+ * @param int $course_id
1753
  * @param bool $force
1754
  *
1755
  * @return bool
1876
  /**
1877
  * Count number of time user has retaken a quiz
1878
  *
1879
+ * @param int $course_id
1880
  * @param bool $force
1881
  *
1882
  * @return int
1992
  do_action( 'learn_press_user_complete_lesson', $lesson_id, $result, $this->get_id() );
1993
 
1994
  do_action( 'learn-press/user-completed-lesson', $lesson_id, $course_id, $this->get_id() );
1995
+ } catch ( Exception $ex ) {
 
1996
  $result = $return_wp_error ? new WP_Error( $ex->getCode(), $ex->getMessage() ) : false;
1997
  }
1998
 
2187
  *
2188
  * @since 3.1.0
2189
  *
2190
+ * @param int[] $access_level
2191
+ * @param int $course_id
2192
  * @param string $compare
2193
  *
2194
  * @return bool
2399
  global $wpdb;
2400
 
2401
  $course = learn_press_get_course( $course_id );
2402
+ $user_id = $this->get_id();
2403
 
2404
  if ( $course->is_required_enroll() && ! $force ) {
2405
 
2418
  }
2419
 
2420
  $user_item_api = new LP_User_Item_CURD();
2421
+ $course_item = $user_item_api->get_item_by( array(
2422
+ 'item_id' => $course_id,
2423
+ 'ref_id' => $order_id,
2424
+ 'user_id' => $user_id
2425
+ ) );
2426
 
2427
  if ( ! $course_item ) {
2428
  $course_item = LP_User_Item::get_empty_item();
2435
  $course_item['item_id'] = $course_id;
2436
  $course_item['item_type'] = learn_press_get_post_type( $course_id );
2437
  $course_item['ref_id'] = $order_id;
2438
+ $course_item['ref_type'] = ( $order_id != 0 ) ? learn_press_get_post_type( $order_id ) : LP_ORDER_CPT;
2439
  $course_item['start_time'] = $date->toSql();
2440
  $course_item['start_time_gmt'] = $date->toSql( false );
2441
 
2442
  $user_course = new LP_User_Item_Course( $course_item );
2443
  $user_course->set_status( 'enrolled' );
2444
+ $user_course->set_end_time_gmt( '0000-00-00 00:00:00' );
2445
+ if ( $user_course->update() ) {
2446
+ $return = true;
2447
+ }
2448
 
2449
  learn_press_remove_message( '', 'error' );
2450
  $user_id = is_user_logged_in() ? $this->get_id() : 0;
languages/learnpress.pot CHANGED
@@ -2,13 +2,13 @@
2
  # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
3
  # This file is distributed under the same license as the PACKAGE package.
4
  # FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
5
- #
6
  #, fuzzy
7
  msgid ""
8
  msgstr ""
9
  "Project-Id-Version: Package Name\n"
10
  "Report-Msgid-Bugs-To: \n"
11
- "POT-Creation-Date: 2019-01-08 16:54+0700\n"
12
  "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
13
  "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
14
  "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,8367 +17,7575 @@ msgstr ""
17
  "Content-Type: text/plain; charset=UTF-8\n"
18
  "Content-Transfer-Encoding: 8bit\n"
19
  "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
 
20
 
21
  #: learnpress.php:379
22
  #, php-format
23
  msgid ""
24
- "LearnPress plugin base directory must be <strong>learnpress/learnpres.php</"
25
- "strong> (case sensitive) to ensure all functions work properly and fully "
26
- "operational (currently <strong>%s</strong>)"
27
  msgstr ""
28
 
29
- #: inc/abstract-settings.php:69
30
- #: inc/admin/settings/abstract-settings-page.php:49
31
- msgid "No setting available."
 
 
32
  msgstr ""
33
 
34
- #: inc/class-lp-ajax.php:109
35
- msgid "Sorry! Registration is not allowed on this site."
 
 
 
 
 
36
  msgstr ""
37
 
38
- #: inc/class-lp-ajax.php:113
39
- msgid "Bad request."
 
 
40
  msgstr ""
41
 
42
- #: inc/class-lp-ajax.php:192
43
- #, php-format
44
- msgid "The order %s has been successfully recovered."
 
45
  msgstr ""
46
 
47
- #: inc/class-lp-ajax.php:246 inc/admin/class-lp-admin-ajax.php:1064
48
- msgid "Profile picture upload failed"
49
  msgstr ""
50
 
51
- #: inc/class-lp-ajax.php:269
52
- msgid "Access denied!"
53
  msgstr ""
54
 
55
- #: inc/class-lp-ajax.php:278
56
- #, php-format
57
- msgid "You have finished this course \"%s\""
58
  msgstr ""
59
 
60
- #: inc/class-lp-ajax.php:281
61
- msgid ""
62
- "Error! You cannot finish this course. Please contact your administrator for "
63
- "more information."
64
  msgstr ""
65
 
66
- #: inc/class-lp-ajax.php:314
67
- msgid "Error! Invalid lesson or failed security check."
68
  msgstr ""
69
 
70
- #: inc/class-lp-ajax.php:324
71
- #, php-format
72
- msgid "Congrats! You have completed \"%s\"."
73
  msgstr ""
74
 
75
- #: inc/class-lp-ajax.php:363
76
- msgid "Error! Invalid course or failed security check."
77
  msgstr ""
78
 
79
- #: inc/class-lp-ajax.php:367
80
- msgid "Error!"
81
  msgstr ""
82
 
83
- #: inc/class-lp-ajax.php:369
84
- #, php-format
85
- msgid "You have retaken the course \"%s\""
86
  msgstr ""
87
 
88
- #: inc/class-lp-ajax.php:373
89
- msgid "Error! You can not retake the course"
90
  msgstr ""
91
 
92
- #: inc/class-lp-assets.php:48 inc/lp-core-functions.php:2256
93
- msgid "OK"
94
  msgstr ""
95
 
96
- #: inc/class-lp-assets.php:49 inc/class-lp-install.php:505
97
- #: inc/lp-core-functions.php:2257 inc/admin/class-lp-admin-ajax.php:861
98
- #: inc/admin/class-lp-admin.php:215 inc/custom-post-types/course.php:864
99
- #: inc/order/class-lp-order.php:935 templates/checkout/form-login.php:103
100
- msgid "Cancel"
101
  msgstr ""
102
 
103
- #: inc/class-lp-assets.php:50 inc/class-lp-gdpr.php:426
104
- #: inc/lp-core-functions.php:2258
105
- #: inc/libraries/meta-box/inc/fields/checkbox.php:53
106
- msgid "Yes"
107
  msgstr ""
108
 
109
- #: inc/class-lp-assets.php:51 inc/class-lp-gdpr.php:426
110
- #: inc/lp-core-functions.php:2259
111
- #: inc/libraries/meta-box/inc/fields/checkbox.php:53
112
- #: templates/content-quiz/intro.php:25
113
- msgid "No"
114
  msgstr ""
115
 
116
- #: inc/class-lp-assets.php:58 inc/class-lp-assets.php:65
117
- #: inc/shortcodes/class-lp-shortcode-become-a-teacher.php:124
118
- #: templates/checkout/payment.php:20
119
- msgid "Processing"
120
  msgstr ""
121
 
122
- #: inc/class-lp-assets.php:59 inc/class-lp-assets.php:66
123
- msgid "Redirecting"
124
  msgstr ""
125
 
126
- #: inc/class-lp-assets.php:60
127
- msgid "Invalid field"
128
  msgstr ""
129
 
130
- #: inc/class-lp-assets.php:61 inc/attributes/course.php:103
131
- msgid "Unknown error"
132
  msgstr ""
133
 
134
- #: inc/class-lp-assets.php:62 templates/checkout/payment.php:19
135
- msgid "Place order"
136
  msgstr ""
137
 
138
- #: inc/class-lp-backward-plugins.php:40
139
- msgid ""
140
- "There are some add-ons had gone outdated and might conflict with "
141
- "<strong>LearnPress</strong> that need to be deactivated. Please upgrade them "
142
- "to the newest version to ensure stability and performance of your site."
143
  msgstr ""
144
 
145
- #: inc/class-lp-backward-plugins.php:95
146
- #, php-format
147
- msgid ""
148
- "LearnPress plugin slug should be <strong>%s</strong> to make sure it works "
149
- "properly. Currently, it is <strong>%s</strong>. Please correct it's name and "
150
- "active again. <a href=\"%s\">Back</a>"
151
  msgstr ""
152
 
153
- #: inc/class-lp-breadcrumb.php:124
154
- msgid "Error 404"
155
  msgstr ""
156
 
157
- #: inc/class-lp-breadcrumb.php:223
158
- #, php-format
159
- msgid "Courses tagged &ldquo;%s&rdquo;"
160
  msgstr ""
161
 
162
- #: inc/class-lp-breadcrumb.php:278
163
- #, php-format
164
- msgid "Posts tagged &ldquo;%s&rdquo;"
165
  msgstr ""
166
 
167
- #: inc/class-lp-breadcrumb.php:355
168
- #, php-format
169
- msgid "Author: %s"
170
  msgstr ""
171
 
172
- #: inc/class-lp-breadcrumb.php:388
173
- #, php-format
174
- msgid "Search results for &ldquo;%s&rdquo;"
175
  msgstr ""
176
 
177
- #: inc/class-lp-breadcrumb.php:397
178
- #, php-format
179
- msgid "Page %d"
180
  msgstr ""
181
 
182
- #: inc/class-lp-checkout.php:160 inc/class-lp-checkout.php:425
183
- msgid "Please enter your email."
184
  msgstr ""
185
 
186
- #: inc/class-lp-checkout.php:165
187
- msgid "You must accept our Terms & Conditions."
188
  msgstr ""
189
 
190
- #: inc/class-lp-checkout.php:210
191
- #: inc/shortcodes/class-lp-shortcode-register-form.php:64
192
- #: inc/shortcodes/class-lp-shortcode-register-form.php:66
193
- #: templates/checkout/form-login.php:63
194
- msgid "Username"
195
  msgstr ""
196
 
197
- #: inc/class-lp-checkout.php:211
198
- #: inc/shortcodes/class-lp-shortcode-login-form.php:69
199
- #: inc/shortcodes/class-lp-shortcode-login-form.php:71
200
- #: inc/shortcodes/class-lp-shortcode-register-form.php:80
201
- #: inc/shortcodes/class-lp-shortcode-register-form.php:82
202
- #: inc/user/class-lp-profile.php:336 templates/checkout/form-login.php:70
203
- msgid "Password"
204
  msgstr ""
205
 
206
- #: inc/class-lp-checkout.php:267 inc/class-lp-checkout.php:276
207
- #: inc/class-lp-checkout.php:315
208
- #, php-format
209
- msgid "Error %d: Unable to create order. Please try again."
210
  msgstr ""
211
 
212
- #: inc/class-lp-checkout.php:309
213
- msgid "Item does not exist!"
214
  msgstr ""
215
 
216
- #: inc/class-lp-checkout.php:339
217
- msgid "Unable to checkout. Order creation failed."
218
  msgstr ""
219
 
220
- #: inc/class-lp-checkout.php:416
221
- msgid "Please enter username."
222
  msgstr ""
223
 
224
- #: inc/class-lp-checkout.php:420
225
- msgid "Please enter user password"
226
  msgstr ""
227
 
228
- #: inc/class-lp-checkout.php:505
229
- msgid "No payment method is selected"
230
  msgstr ""
231
 
232
- #: inc/class-lp-checkout.php:545 templates/checkout/empty-cart.php:19
233
- msgid "Your cart is currently empty."
234
  msgstr ""
235
 
236
- #: inc/class-lp-checkout.php:564
237
- #, php-format
238
- msgid "Item \"%s\" is not purchasable."
239
  msgstr ""
240
 
241
- #: inc/class-lp-emails.php:136 inc/class-lp-emails.php:143
242
- msgid "Cheatin&#8217; huh?"
243
  msgstr ""
244
 
245
- #: inc/class-lp-forms-handler.php:39 inc/class-lp-forms-handler.php:116
246
- #: inc/class-lp-forms-handler.php:200
247
- #, php-format
248
- msgid "Field \"%s\" is required."
249
  msgstr ""
250
 
251
- #: inc/class-lp-forms-handler.php:52
252
- msgid "Thank you! Your message has been sent."
253
  msgstr ""
254
 
255
- #: inc/class-lp-forms-handler.php:76
256
- msgid "Your email does not exist!"
257
  msgstr ""
258
 
259
- #: inc/class-lp-forms-handler.php:150
260
- msgid "Login successfully."
261
  msgstr ""
262
 
263
- #: inc/class-lp-forms-handler.php:239
264
- msgid "Register successfully."
265
  msgstr ""
266
 
267
- #: inc/class-lp-forms-handler.php:264
268
- msgid "Password is too short!"
269
  msgstr ""
270
 
271
- #: inc/class-lp-forms-handler.php:268
272
- msgid "Password can not have spacing!"
273
  msgstr ""
274
 
275
- #: inc/class-lp-forms-handler.php:272
276
- msgid "Password must include at least one letter!"
277
  msgstr ""
278
 
279
- #: inc/class-lp-forms-handler.php:276
280
- msgid "Password must include at least one capitalized letter!"
281
  msgstr ""
282
 
283
- #: inc/class-lp-forms-handler.php:280
284
- msgid "Password must include at least one number!"
285
  msgstr ""
286
 
287
- #: inc/class-lp-forms-handler.php:284
288
- msgid "Password must include at least one of these characters ~!@#$%^&*() !"
289
  msgstr ""
290
 
291
- #: inc/class-lp-gdpr.php:31 inc/class-lp-market-products.php:12
292
- #: inc/admin/class-lp-admin-menu.php:90 inc/admin/class-lp-admin.php:103
293
- #: inc/admin/class-lp-admin.php:105 inc/admin/lp-admin-functions.php:1597
294
- #: inc/admin/settings/class-lp-settings-emails.php:161
295
- msgid "LearnPress"
296
  msgstr ""
297
 
298
- #: inc/class-lp-gdpr.php:49
299
- msgid "LearnPress Owned Courses"
300
  msgstr ""
301
 
302
- #: inc/class-lp-gdpr.php:57
303
- msgid "LearnPress Orders"
304
  msgstr ""
305
 
306
- #: inc/class-lp-gdpr.php:65
307
- msgid "LearnPress Purchased Courses"
308
  msgstr ""
309
 
310
- #: inc/class-lp-gdpr.php:73
311
- msgid "LearnPress User Profile"
312
  msgstr ""
313
 
314
- #: inc/class-lp-gdpr.php:98
315
- msgid "Profile Settings"
316
  msgstr ""
317
 
318
- #: inc/class-lp-gdpr.php:147
319
- msgid "Order ID"
320
  msgstr ""
321
 
322
- #: inc/class-lp-gdpr.php:151
323
- msgid "Order Date"
324
  msgstr ""
325
 
326
- #: inc/class-lp-gdpr.php:155
327
- msgid "Order status"
328
  msgstr ""
329
 
330
- #: inc/class-lp-gdpr.php:159
331
- msgid "Order Total"
332
  msgstr ""
333
 
334
- #: inc/class-lp-gdpr.php:165
335
- #: inc/admin/settings/class-lp-settings-profile.php:165
336
- #: inc/admin/sub-menus/class-lp-submenu-statistics.php:22
337
- #: inc/admin/sub-menus/class-lp-submenu-statistics.php:29
338
- #: inc/custom-post-types/order.php:903 inc/custom-post-types/order.php:904
339
- #: inc/custom-post-types/order.php:908 inc/user/class-lp-profile.php:312
340
- msgid "Orders"
341
  msgstr ""
342
 
343
- #: inc/class-lp-gdpr.php:213 inc/class-lp-gdpr.php:332
344
- msgid "Course Author"
345
  msgstr ""
346
 
347
- #: inc/class-lp-gdpr.php:217 inc/class-lp-gdpr.php:336
348
- msgid "Course Name"
349
  msgstr ""
350
 
351
- #: inc/class-lp-gdpr.php:221 inc/class-lp-gdpr.php:340
352
- msgid "Course Date"
353
  msgstr ""
354
 
355
- #: inc/class-lp-gdpr.php:225 inc/class-lp-gdpr.php:344
356
- msgid "Course URL"
357
  msgstr ""
358
 
359
- #: inc/class-lp-gdpr.php:231
360
- msgid "Owned Course"
361
  msgstr ""
362
 
363
- #: inc/class-lp-gdpr.php:264 inc/class-lp-gdpr.php:400
364
- msgid "Item Name"
365
  msgstr ""
366
 
367
- #: inc/class-lp-gdpr.php:268 inc/class-lp-gdpr.php:404
368
- msgid "Item Type"
369
  msgstr ""
370
 
371
- #: inc/class-lp-gdpr.php:272 inc/class-lp-gdpr.php:408
372
- msgid "Item URL"
373
  msgstr ""
374
 
375
- #: inc/class-lp-gdpr.php:279 inc/class-lp-gdpr.php:432
376
- msgid "Course Items"
377
  msgstr ""
378
 
379
- #: inc/class-lp-gdpr.php:348
380
- msgid "Enrolled Date"
381
  msgstr ""
382
 
383
- #: inc/class-lp-gdpr.php:352
384
- msgid "Finished Date"
385
  msgstr ""
386
 
387
- #: inc/class-lp-gdpr.php:356
388
- msgid "Course Status"
389
  msgstr ""
390
 
391
- #: inc/class-lp-gdpr.php:360
392
- msgid "Course Grade"
393
  msgstr ""
394
 
395
- #: inc/class-lp-gdpr.php:361 templates/content-quiz/result.php:33
396
- msgid "Ungraded"
397
  msgstr ""
398
 
399
- #: inc/class-lp-gdpr.php:366
400
- msgid "Purchased Course"
401
  msgstr ""
402
 
403
- #: inc/class-lp-gdpr.php:415 inc/admin/meta-box/fields/list-emails.php:30
404
- #: inc/admin/meta-box/fields/payment-order.php:32
405
- #: inc/admin/views/meta-boxes/order/details.php:57
406
- #: inc/custom-post-types/order.php:773
407
- #: templates/emails/order-items-table.php:53
408
- #: templates/emails/plain/order-items-table.php:30
409
- #: templates/profile/tabs/orders/list.php:34
410
- msgid "Status"
411
  msgstr ""
412
 
413
- #: inc/class-lp-gdpr.php:420
414
- msgid "Grade"
415
  msgstr ""
416
 
417
- #: inc/class-lp-gdpr.php:425 inc/admin/lp-admin-functions.php:1222
418
- #: inc/admin/views/statistics/orders.php:63
419
- #: inc/user-item/class-lp-user-item-quiz.php:107
420
- #: inc/user-item/class-lp-user-item.php:548
421
- #: templates/content-lesson/button-complete.php:36
422
- msgid "Completed"
423
  msgstr ""
424
 
425
- #: inc/class-lp-install.php:504
426
- msgid ""
427
- "It seems like you have updated LearnPress from an older version and there "
428
- "are some outdated courses or data that need to be upgraded."
429
  msgstr ""
430
 
431
- #: inc/class-lp-install.php:505
432
- msgid "Do not ask again."
433
  msgstr ""
434
 
435
- #: inc/class-lp-install.php:505
436
- msgid "Ok"
437
  msgstr ""
438
 
439
- #: inc/class-lp-install.php:506
440
- #: inc/admin/views/tools/database/html-upgrade-database.php:17
441
- msgid "Upgrade now"
442
  msgstr ""
443
 
444
- #: inc/class-lp-install.php:506
445
- msgid "No, thank!"
446
  msgstr ""
447
 
448
- #: inc/class-lp-install.php:513
449
- msgid ""
450
- "LearnPress has been updated and the database needs to be upgraded before you "
451
- "can work with it. Please notify the site administrator."
452
  msgstr ""
453
 
454
- #: inc/class-lp-install.php:532
455
- msgid "Thank you for using LearnPress"
456
  msgstr ""
457
 
458
- #: inc/class-lp-market-products.php:13
459
- msgid "Ahihi"
460
  msgstr ""
461
 
462
- #: inc/class-lp-multi-language.php:52
463
- #: inc/admin/sub-menus/class-lp-submenu-settings.php:14
464
- #: inc/admin/views/quiz/question-meta.php:12
465
- #: inc/custom-post-types/question.php:294 inc/user/class-lp-profile.php:325
466
- msgid "Settings"
467
  msgstr ""
468
 
469
- #: inc/class-lp-multi-language.php:53 inc/libraries/meta-box/inc/core.php:38
470
- #: inc/libraries/meta-box/inc/about/sections/welcome.php:19
471
- msgid "Documentation"
472
  msgstr ""
473
 
474
- #: inc/class-lp-multi-language.php:54
475
- #: inc/admin/sub-menus/class-lp-submenu-addons.php:15
476
- msgid "Add-ons"
477
  msgstr ""
478
 
479
- #: inc/class-lp-page-controller.php:129
480
- msgid "You can not view this item or it does not exist!"
481
  msgstr ""
482
 
483
- #: inc/class-lp-page-controller.php:462
484
- #, php-format
485
- msgid "The user %s is not available!"
486
  msgstr ""
487
 
488
- #: inc/class-lp-preview-course.php:35
489
- msgid "Preview Course"
490
  msgstr ""
491
 
492
- #: inc/class-lp-preview-course.php:80 inc/class-lp-preview-course.php:97
493
- msgid "Invalid preview item."
494
  msgstr ""
495
 
496
- #: inc/class-lp-preview-course.php:103
497
- msgid "Access denied."
 
498
  msgstr ""
499
 
500
- #: inc/class-lp-preview-course.php:176
501
- #, php-format
502
- msgid "You are in preview mode. Continue <a href=\"%s\">editing</a>?"
503
  msgstr ""
504
 
505
- #: inc/class-lp-query-list-table.php:28 inc/custom-post-types/course.php:99
506
- msgid "item"
507
  msgstr ""
508
 
509
- #: inc/class-lp-query-list-table.php:29
510
- msgid "items"
511
  msgstr ""
512
 
513
- #: inc/class-lp-query-list-table.php:142
514
- msgid "Displaying {{from}} to {{to}} of {{total}} {{item_name}}."
515
  msgstr ""
516
 
517
- #: inc/class-lp-query-list-table.php:144
518
- msgid "Displaying {{from}} to {{to}} of {{total}}."
519
  msgstr ""
520
 
521
- #: inc/class-lp-repair-database.php:597
522
- #, php-format
523
- msgid "The method %s is not callable."
524
  msgstr ""
525
 
526
- #: inc/class-lp-request-handler.php:148
527
- msgid "You have already purchased this course and haven't finished it."
528
  msgstr ""
529
 
530
- #: inc/class-lp-request-handler.php:156
531
- msgid ""
532
- "You have already purchased this course and the order is still processing..."
533
  msgstr ""
534
 
535
- #: inc/class-lp-request-handler.php:179
536
- msgid "You have finished course."
537
  msgstr ""
538
 
539
- #: inc/class-lp-request-handler.php:195
540
- msgid "You have to purchase the course before enrolling."
541
  msgstr ""
542
 
543
- #: inc/class-lp-request-handler.php:232
544
- msgid "Invalid action."
545
  msgstr ""
546
 
547
- #: inc/class-lp-request-handler.php:291 inc/cart/class-lp-cart.php:459
548
- msgid "Checkout page hasn't been setup"
549
  msgstr ""
550
 
551
- #: inc/class-lp-request-handler.php:297 inc/class-lp-request-handler.php:332
552
- #, php-format
553
- msgid "You can not enroll course &quot;%s&quot"
554
  msgstr ""
555
 
556
- #: inc/class-lp-request-handler.php:324
557
- #: inc/course/lp-course-functions.php:1151
558
- msgid "Invalid request!"
559
  msgstr ""
560
 
561
- #: inc/class-lp-request-handler.php:349
562
- #, php-format
563
- msgid "Congrats! You have enrolled &quot;%s&quot"
564
  msgstr ""
565
 
566
- #: inc/class-lp-request-handler.php:379
567
- msgid "Checkout page hasn't been setup or page does not exists."
568
  msgstr ""
569
 
570
- #: inc/class-lp-request-handler.php:381
571
- msgid "Checkout error! Please contact with admin for getting more information."
572
  msgstr ""
573
 
574
- #: inc/class-lp-shortcodes.php:225
575
- msgid "Forgot password?"
576
  msgstr ""
577
 
578
- #: inc/class-lp-shortcodes.php:227
579
- msgid "Create new account"
580
  msgstr ""
581
 
582
- #: inc/class-lp-strings.php:16 inc/lp-strings.php:7
583
- #, php-format
584
- msgid "Do you want to redo quiz \"%s\"?"
585
  msgstr ""
586
 
587
- #: inc/class-lp-strings.php:17 inc/lp-strings.php:8
588
- #, php-format
589
- msgid "Do you want to complete quiz \"%s\"?"
590
  msgstr ""
591
 
592
- #: inc/class-lp-strings.php:18 inc/lp-strings.php:9
593
- #, php-format
594
- msgid "Do you want to complete lesson \"%s\"?"
595
  msgstr ""
596
 
597
- #: inc/class-lp-strings.php:19 inc/lp-strings.php:10
598
- #, php-format
599
- msgid "Do you want to finish course \"%s\"?"
600
  msgstr ""
601
 
602
- #: inc/class-lp-strings.php:20 inc/lp-strings.php:11
603
- #, php-format
604
- msgid "Do you want to retake course \"%s\"?"
605
  msgstr ""
606
 
607
- #: inc/class-lp-widget.php:213
608
- #, php-format
609
- msgid "Function %s should be overwritten in child class"
610
  msgstr ""
611
 
612
- #: inc/lp-core-functions.php:351 inc/lp-template-functions.php:2673
613
- #: inc/admin/settings/class-lp-settings-courses.php:150
614
- #: inc/course/lp-course-functions.php:581 inc/custom-post-types/lesson.php:184
615
- msgid "Lesson"
616
  msgstr ""
617
 
618
- #: inc/lp-core-functions.php:352 inc/lp-template-functions.php:2663
619
- #: inc/admin/settings/class-lp-settings-courses.php:157
620
- #: inc/course/lp-course-functions.php:582
621
- #: inc/custom-post-types/question.php:337 inc/custom-post-types/quiz.php:92
622
- #: templates/profile/tabs/quizzes.php:38
623
- msgid "Quiz"
624
  msgstr ""
625
 
626
- #: inc/lp-core-functions.php:726 inc/admin/class-lp-modal-search-items.php:210
627
- #: inc/admin/class-lp-modal-search-users.php:135
628
- msgid "<"
629
  msgstr ""
630
 
631
- #: inc/lp-core-functions.php:727 inc/admin/class-lp-modal-search-items.php:211
632
- #: inc/admin/class-lp-modal-search-users.php:136
633
- msgid ">"
634
  msgstr ""
635
 
636
- #: inc/lp-core-functions.php:805
637
- msgid "Minute(s)"
638
  msgstr ""
639
 
640
- #: inc/lp-core-functions.php:806
641
- msgid "Hour(s)"
642
  msgstr ""
643
 
644
- #: inc/lp-core-functions.php:807
645
- msgid "Day(s)"
646
  msgstr ""
647
 
648
- #: inc/lp-core-functions.php:808
649
- msgid "Week(s)"
650
  msgstr ""
651
 
652
- #: inc/lp-core-functions.php:953
653
- msgid "Left"
654
  msgstr ""
655
 
656
- #: inc/lp-core-functions.php:954
657
- msgid "Right"
658
  msgstr ""
659
 
660
- #: inc/lp-core-functions.php:955
661
- msgid "Left with space"
662
  msgstr ""
663
 
664
- #: inc/lp-core-functions.php:956
665
- msgid "Right with space"
666
  msgstr ""
667
 
668
- #: inc/lp-core-functions.php:1020
669
- msgid "Afghan afghani"
670
  msgstr ""
671
 
672
- #: inc/lp-core-functions.php:1021
673
- msgid "Albanian lek"
674
  msgstr ""
675
 
676
- #: inc/lp-core-functions.php:1022
677
- msgid "Algerian dinar"
678
  msgstr ""
679
 
680
- #: inc/lp-core-functions.php:1023
681
- msgid "Euro"
682
  msgstr ""
683
 
684
- #: inc/lp-core-functions.php:1024
685
- msgid "Angolan kwanza"
686
  msgstr ""
687
 
688
- #: inc/lp-core-functions.php:1025
689
- msgid "East Caribbean dollar"
690
  msgstr ""
691
 
692
- #: inc/lp-core-functions.php:1026
693
- msgid "Argentine peso"
694
  msgstr ""
695
 
696
- #: inc/lp-core-functions.php:1027
697
- msgid "Armenian dram"
698
  msgstr ""
699
 
700
- #: inc/lp-core-functions.php:1028
701
- msgid "Aruban florin"
702
  msgstr ""
703
 
704
- #: inc/lp-core-functions.php:1029
705
- msgid "Australian dollar"
706
  msgstr ""
707
 
708
- #: inc/lp-core-functions.php:1030
709
- msgid "Azerbaijani manat"
710
  msgstr ""
711
 
712
- #: inc/lp-core-functions.php:1031
713
- msgid "Bahamian dollar"
714
  msgstr ""
715
 
716
- #: inc/lp-core-functions.php:1032
717
- msgid "Bahraini dinar"
718
  msgstr ""
719
 
720
- #: inc/lp-core-functions.php:1033
721
- msgid "Bangladeshi taka"
722
  msgstr ""
723
 
724
- #: inc/lp-core-functions.php:1034
725
- msgid "Barbadian dollar"
726
  msgstr ""
727
 
728
- #: inc/lp-core-functions.php:1035
729
- msgid "Belarusian ruble"
730
  msgstr ""
731
 
732
- #: inc/lp-core-functions.php:1036
733
- msgid "Belizean dollar"
734
  msgstr ""
735
 
736
- #: inc/lp-core-functions.php:1037
737
- msgid "West African CFA franc"
738
  msgstr ""
739
 
740
- #: inc/lp-core-functions.php:1038
741
- msgid "Bermudian dollar"
742
  msgstr ""
743
 
744
- #: inc/lp-core-functions.php:1039
745
- msgid "Bhutanese ngultrum"
746
  msgstr ""
747
 
748
- #: inc/lp-core-functions.php:1040
749
- msgid "Bolivian boliviano"
750
  msgstr ""
751
 
752
- #: inc/lp-core-functions.php:1041
753
- msgid "US dollar"
754
  msgstr ""
755
 
756
- #: inc/lp-core-functions.php:1042
757
- msgid "Bosnia and Herzegovina convertible mark"
758
  msgstr ""
759
 
760
- #: inc/lp-core-functions.php:1043
761
- msgid "Botswana pula"
762
  msgstr ""
763
 
764
- #: inc/lp-core-functions.php:1044
765
- msgid "Brazilian real"
766
  msgstr ""
767
 
768
- #: inc/lp-core-functions.php:1045
769
- msgid "Brunei dollar"
770
  msgstr ""
771
 
772
- #: inc/lp-core-functions.php:1046
773
- msgid "Bulgarian lev"
774
  msgstr ""
775
 
776
- #: inc/lp-core-functions.php:1047
777
- msgid "Burmese kyat"
778
  msgstr ""
779
 
780
- #: inc/lp-core-functions.php:1048
781
- msgid "Burundian franc"
782
  msgstr ""
783
 
784
- #: inc/lp-core-functions.php:1049
785
- msgid "Cambodian riel"
786
  msgstr ""
787
 
788
- #: inc/lp-core-functions.php:1050
789
- msgid "Central African CFA franc"
790
  msgstr ""
791
 
792
- #: inc/lp-core-functions.php:1051
793
- msgid "Canadian dollar"
794
  msgstr ""
795
 
796
- #: inc/lp-core-functions.php:1052
797
- msgid "Cape Verdean escudo"
798
  msgstr ""
799
 
800
- #: inc/lp-core-functions.php:1053
801
- msgid "Cayman Islands dollar"
802
- msgstr ""
 
 
803
 
804
- #: inc/lp-core-functions.php:1054
805
- msgid "Chilean peso"
806
- msgstr ""
 
 
807
 
808
- #: inc/lp-core-functions.php:1055
809
- msgid "Chinese renminbi"
810
- msgstr ""
 
 
811
 
812
- #: inc/lp-core-functions.php:1056
813
- msgid "Colombian peso"
814
- msgstr ""
 
 
815
 
816
- #: inc/lp-core-functions.php:1057
817
- msgid "Comorian franc"
 
 
 
818
  msgstr ""
819
 
820
- #: inc/lp-core-functions.php:1058
821
- msgid "Congolese franc"
822
  msgstr ""
823
 
824
- #: inc/lp-core-functions.php:1059
825
- msgid "New Zealand dollar"
 
 
 
826
  msgstr ""
827
 
828
- #: inc/lp-core-functions.php:1060
829
- msgid "Costa Rican colón"
830
  msgstr ""
831
 
832
- #: inc/lp-core-functions.php:1061
833
- msgid "Croatian kuna"
834
  msgstr ""
835
 
836
- #: inc/lp-core-functions.php:1062
837
- msgid "Cuban peso"
838
  msgstr ""
839
 
840
- #: inc/lp-core-functions.php:1063
841
- msgid "Netherlands Antilles guilder"
842
  msgstr ""
843
 
844
- #: inc/lp-core-functions.php:1064
845
- msgid "Czech koruna"
846
  msgstr ""
847
 
848
- #: inc/lp-core-functions.php:1065
849
- msgid "Danish krone"
850
  msgstr ""
851
 
852
- #: inc/lp-core-functions.php:1066
853
- msgid "Djiboutian franc"
 
854
  msgstr ""
855
 
856
- #: inc/lp-core-functions.php:1067
857
- msgid "Dominican peso"
 
858
  msgstr ""
859
 
860
- #: inc/lp-core-functions.php:1068
861
- msgid "Egyptian pound"
 
862
  msgstr ""
863
 
864
- #: inc/lp-core-functions.php:1069
865
- msgid "Salvadoran colón"
 
866
  msgstr ""
867
 
868
- #: inc/lp-core-functions.php:1070
869
- msgid "Eritrean nakfa"
 
870
  msgstr ""
871
 
872
- #: inc/lp-core-functions.php:1071
873
- msgid "Ethiopian birr"
 
874
  msgstr ""
875
 
876
- #: inc/lp-core-functions.php:1072
877
- msgid "Falkland Islands pound"
 
878
  msgstr ""
879
 
880
- #: inc/lp-core-functions.php:1073
881
- msgid "Fijian dollar"
 
 
 
 
 
 
 
882
  msgstr ""
883
 
884
- #: inc/lp-core-functions.php:1074
885
- msgid "CFP franc"
 
 
886
  msgstr ""
887
 
888
- #: inc/lp-core-functions.php:1075
889
- msgid "Gambian dalasi"
 
 
 
890
  msgstr ""
891
 
892
- #: inc/lp-core-functions.php:1076
893
- msgid "Georgian lari"
 
894
  msgstr ""
895
 
896
- #: inc/lp-core-functions.php:1077
897
- msgid "Ghanian cedi"
898
  msgstr ""
899
 
900
- #: inc/lp-core-functions.php:1078
901
- msgid "Gibraltar pound"
902
  msgstr ""
903
 
904
- #: inc/lp-core-functions.php:1079
905
- msgid "Guatemalan quetzal"
906
  msgstr ""
907
 
908
- #: inc/lp-core-functions.php:1080
909
- msgid "British pound"
910
  msgstr ""
911
 
912
- #: inc/lp-core-functions.php:1081
913
- msgid "Guinean franc"
914
  msgstr ""
915
 
916
- #: inc/lp-core-functions.php:1082
917
- msgid "Guyanese dollar"
918
  msgstr ""
919
 
920
- #: inc/lp-core-functions.php:1083
921
- msgid "Haitian gourde"
922
  msgstr ""
923
 
924
- #: inc/lp-core-functions.php:1084
925
- msgid "Honduran lempira"
926
  msgstr ""
927
 
928
- #: inc/lp-core-functions.php:1085
929
- msgid "Hong Kong dollar"
930
  msgstr ""
931
 
932
- #: inc/lp-core-functions.php:1086
933
- msgid "Hungarian forint"
934
  msgstr ""
935
 
936
- #: inc/lp-core-functions.php:1087
937
- msgid "Icelandic króna"
 
 
 
 
 
938
  msgstr ""
939
 
940
- #: inc/lp-core-functions.php:1088
941
- msgid "Indian rupee"
 
 
 
 
 
942
  msgstr ""
943
 
944
- #: inc/lp-core-functions.php:1089
945
- msgid "Indonesian rupiah"
 
946
  msgstr ""
947
 
948
- #: inc/lp-core-functions.php:1090
949
- msgid "Iranian rial"
 
950
  msgstr ""
951
 
952
- #: inc/lp-core-functions.php:1091
953
- msgid "Iraqi dinar"
 
954
  msgstr ""
955
 
956
- #: inc/lp-core-functions.php:1092
957
- msgid "Israeli new sheqel"
 
958
  msgstr ""
959
 
960
- #: inc/lp-core-functions.php:1093
961
- msgid "Jamaican dollar"
 
 
 
962
  msgstr ""
963
 
964
- #: inc/lp-core-functions.php:1094
965
- msgid "Japanese yen "
 
966
  msgstr ""
967
 
968
- #: inc/lp-core-functions.php:1095
969
- msgid "Jordanian dinar"
970
  msgstr ""
971
 
972
- #: inc/lp-core-functions.php:1096
973
- msgid "Kazakhstani tenge"
 
974
  msgstr ""
975
 
976
- #: inc/lp-core-functions.php:1097
977
- msgid "Kenyan shilling"
 
978
  msgstr ""
979
 
980
- #: inc/lp-core-functions.php:1098
981
- msgid "North Korean won"
 
982
  msgstr ""
983
 
984
- #: inc/lp-core-functions.php:1099
985
- msgid "Kuwaiti dinar"
 
986
  msgstr ""
987
 
988
- #: inc/lp-core-functions.php:1100
989
- msgid "Kyrgyzstani som"
 
 
 
990
  msgstr ""
991
 
992
- #: inc/lp-core-functions.php:1101
993
- msgid "South Korean won"
994
  msgstr ""
995
 
996
- #: inc/lp-core-functions.php:1102
997
- msgid "Lao kip"
998
  msgstr ""
999
 
1000
- #: inc/lp-core-functions.php:1103
1001
- msgid "Latvian lats"
1002
  msgstr ""
1003
 
1004
- #: inc/lp-core-functions.php:1104
1005
- msgid "Lebanese pound"
1006
  msgstr ""
1007
 
1008
- #: inc/lp-core-functions.php:1105
1009
- msgid "Lesotho loti"
1010
  msgstr ""
1011
 
1012
- #: inc/lp-core-functions.php:1106
1013
- msgid "Liberian dollar"
1014
  msgstr ""
1015
 
1016
- #: inc/lp-core-functions.php:1107 inc/lp-core-functions.php:1178
1017
- msgid "Libyan dinar"
1018
  msgstr ""
1019
 
1020
- #: inc/lp-core-functions.php:1108
1021
- msgid "Swiss franc"
1022
  msgstr ""
1023
 
1024
- #: inc/lp-core-functions.php:1109
1025
- msgid "Lithuanian litas"
1026
  msgstr ""
1027
 
1028
- #: inc/lp-core-functions.php:1110
1029
- msgid "Macanese pataca"
1030
  msgstr ""
1031
 
1032
- #: inc/lp-core-functions.php:1111
1033
- msgid "Macedonian denar"