Tutor LMS – eLearning and online course solution - Version 1.3.1

Version Description

  • 22 May, 2019 =

  • Added: status in the purchase history list

  • Added: Shortcode for the coruse query, full shortcode [tutor_course id="20,64" exclude_ids="567,332" category="18,19" order="desc" count="3"]

  • Added: a simple shortcode builder to build [tutor_course] Shortcode from classic editor

  • Added: Tutor course widget to display course to sidebar

  • Added: utils()->get_raw_course_price($course_id), it will be return to your regular price and sale price as object

  • Added: Course page edit by Pagebuilder integration which supports frontend editing

  • Added: `$size

Download this release

Release Info

Developer themeum
Plugin Icon wp plugin Tutor LMS – eLearning and online course solution
Version 1.3.1
Comparing to
See all releases

Code changes from version 1.3.0 to 1.3.1

assets/css/tutor-front.css CHANGED
@@ -533,6 +533,9 @@ div[class*="tutor-course-col"] {
533
  -ms-flex-pack: justify;
534
  justify-content: space-between;
535
  }
 
 
 
536
  .tutor-course-header{
537
  position: relative;
538
  }
@@ -4322,3 +4325,19 @@ button.tm-close.tutor-icon-line-cross {
4322
  font-size: 24px;
4323
  }
4324
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  -ms-flex-pack: justify;
534
  justify-content: space-between;
535
  }
536
+ .tutor-course-loop a, .tutor-widget-course a{
537
+ text-decoration: none !important;
538
+ }
539
  .tutor-course-header{
540
  position: relative;
541
  }
4325
  font-size: 24px;
4326
  }
4327
 
4328
+ .label-order-status{
4329
+ padding: 3px 5px;
4330
+ border-radius: 3px;
4331
+ }
4332
+ .label-status-completed{
4333
+ background-color: #4BD863;
4334
+ color: #ffffff;
4335
+ }
4336
+ .label-status-cancelled{
4337
+ background-color: #FD6A03;
4338
+ color: #ffffff;
4339
+ }
4340
+ .label-status-on-hold{
4341
+ background-color: #DB5382;
4342
+ color: #ffffff;
4343
+ }
assets/js/mce-button.js CHANGED
@@ -17,17 +17,90 @@ jQuery(document).ready(function($){
17
  editor.insertContent('[tutor_student_registration_form]');
18
  }
19
  },
20
- {
21
  text: 'Student Dashboard',
22
  onclick: function() {
23
  editor.insertContent('[tutor_dashboard]');
24
  }
25
- },{
26
  text: 'Instructor Registration Form',
27
  onclick: function() {
28
  editor.insertContent('[tutor_instructor_registration_form]');
29
  }
30
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
  ]
32
  });
33
  });
17
  editor.insertContent('[tutor_student_registration_form]');
18
  }
19
  },
20
+ /*{
21
  text: 'Student Dashboard',
22
  onclick: function() {
23
  editor.insertContent('[tutor_dashboard]');
24
  }
25
+ },*/{
26
  text: 'Instructor Registration Form',
27
  onclick: function() {
28
  editor.insertContent('[tutor_instructor_registration_form]');
29
  }
30
  },
31
+ /* {
32
+ text: 'Courses',
33
+ onclick: function() {
34
+ editor.insertContent('[tutor_course]');
35
+ }
36
+ },*/
37
+
38
+
39
+
40
+ {
41
+ text: 'Courses',
42
+ onclick: function() {
43
+ editor.windowManager.open( {
44
+ title: 'Courses Shortcode',
45
+ body: [
46
+ {
47
+ type: 'textbox',
48
+ name: 'id',
49
+ label: 'Course id, seperate by (,) comma',
50
+ value: ''
51
+ },{
52
+ type: 'textbox',
53
+ name: 'exclude_ids',
54
+ label: 'Exclude Course IDS',
55
+ value: ''
56
+ },
57
+ {
58
+ type: 'textbox',
59
+ name: 'category',
60
+ label: 'Category IDS',
61
+ value: ''
62
+ },
63
+ {type: 'listbox',
64
+ name: 'orderby',
65
+ label: 'Order By :',
66
+ onselect: function(e) {
67
+
68
+ },
69
+ 'values': [
70
+ {text: 'ID', value: 'ID'},
71
+ {text: 'title', value: 'title'},
72
+ {text: 'rand', value: 'rand'},
73
+ {text: 'date', value: 'date'},
74
+ {text: 'menu_order', value: 'menu_order'},
75
+ {text: 'post__in', value: 'post__in'},
76
+ ]
77
+ },
78
+ {type: 'listbox',
79
+ name: 'order',
80
+ label: 'Order :',
81
+ onselect: function(e) {
82
+
83
+ },
84
+ 'values': [
85
+ {text: 'DESC', value: 'DESC'},
86
+ {text: 'ASC', value: 'ASC'}
87
+ ]
88
+ },
89
+ ,{
90
+ type: 'textbox',
91
+ name: 'count',
92
+ label: 'Count',
93
+ value: '6',
94
+ }
95
+ ],
96
+ onsubmit: function( e ) {
97
+ editor.insertContent( '[tutor_course id="' + e.data.id + '" exclude_ids="'+e.data.exclude_ids+'" category="'+e.data.category+'" orderby="'+e.data.orderby+'" order="'+e.data.order+'" count="'+e.data.count+'"]');
98
+ }
99
+ });
100
+ }
101
+ }
102
+
103
+
104
  ]
105
  });
106
  });
classes/Admin.php CHANGED
@@ -29,6 +29,9 @@ class Admin{
29
 
30
  //Admin Footer Text
31
  add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
 
 
 
32
  }
33
 
34
  public function register_menu(){
@@ -457,4 +460,9 @@ class Admin{
457
  }
458
 
459
 
 
 
 
 
 
460
  }
29
 
30
  //Admin Footer Text
31
  add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
32
+
33
+ //Register Course Widget
34
+ add_action( 'widgets_init', array($this, 'register_course_widget') );
35
  }
36
 
37
  public function register_menu(){
460
  }
461
 
462
 
463
+ public function register_course_widget(){
464
+ register_widget( 'Tutor\Course_Widget' );
465
+ }
466
+
467
+
468
  }
classes/Course_Widget.php ADDED
@@ -0,0 +1,197 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Widget class
5
+ *
6
+ * @author: themeum
7
+ * @author_uri: https://themeum.com
8
+ * @package Tutor
9
+ * @since v.1.3.1
10
+ */
11
+
12
+ namespace TUTOR;
13
+
14
+ if ( ! defined( 'ABSPATH' ) )
15
+ exit;
16
+
17
+ class Course_Widget extends \WP_Widget {
18
+
19
+ function __construct() {
20
+ parent::__construct(
21
+ 'tutor_course_widget', // Base ID
22
+ esc_html__( 'Tutor Course', 'tutor' ), // Name
23
+ array( 'description' => esc_html__( 'Get the courses and show it anywhere widget support available', 'tutor' ), ) // Args
24
+ );
25
+ }
26
+
27
+ /**
28
+ * Front-end display of widget.
29
+ *
30
+ * @see WP_Widget::widget()
31
+ *
32
+ * @param array $args Widget arguments.
33
+ * @param array $instance Saved values from database.
34
+ */
35
+ public function widget( $args, $instance ) {
36
+ echo $args['before_widget'];
37
+ if ( ! empty( $instance['title'] ) ) {
38
+ echo $args['before_title'] . apply_filters( 'widget_title', $instance['title'] ) . $args['after_title'];
39
+ }
40
+
41
+ $course_post_type = tutor()->course_post_type;
42
+
43
+ $form_args = $instance;
44
+ unset($form_args['title']);
45
+
46
+ $default_args = array(
47
+ 'post_type' => $course_post_type,
48
+ 'post_status' => 'publish',
49
+
50
+ 'id' => '',
51
+ 'exclude_ids' => '',
52
+ 'category' => '',
53
+
54
+ 'orderby' => 'ID',
55
+ 'order' => 'DESC',
56
+ 'count' => '6',
57
+ );
58
+
59
+ $a = array_merge($default_args, $form_args);
60
+
61
+ if ( ! empty($a['id'])){
62
+ $ids = (array) explode(',', $a['id']);
63
+ $a['post__in'] = $ids;
64
+ }
65
+
66
+ if ( ! empty($a['exclude_ids'])){
67
+ $exclude_ids = (array) explode(',', $a['exclude_ids']);
68
+ $a['post__not_in'] = $exclude_ids;
69
+ }
70
+ if ( ! empty($a['category'])){
71
+ $category = (array) explode(',', $a['category']);
72
+
73
+ $a['tax_query'] = array(
74
+ array(
75
+ 'taxonomy' => 'course-category',
76
+ 'field' => 'term_id',
77
+ 'terms' => $category,
78
+ 'operator' => 'IN',
79
+ ),
80
+ );
81
+ }
82
+ $a['posts_per_page'] = (int) $a['count'];
83
+
84
+ wp_reset_query();
85
+ query_posts($a);
86
+ ob_start();
87
+ tutor_load_template('widget.courses');
88
+ $output = ob_get_clean();
89
+ wp_reset_query();
90
+
91
+
92
+ echo $output;
93
+
94
+ echo $args['after_widget'];
95
+ }
96
+
97
+ /**
98
+ * Back-end widget form.
99
+ *
100
+ * @see WP_Widget::form()
101
+ *
102
+ * @param array $instance Previously saved values from database.
103
+ */
104
+ public function form( $instance ) {
105
+ $title = ! empty( $instance['title'] ) ? $instance['title'] : esc_html__( 'New title', 'tutor' );
106
+ $id = ! empty( $instance['id'] ) ? $instance['id'] : '';
107
+ $exclude_ids = ! empty( $instance['exclude_ids'] ) ? $instance['exclude_ids'] : '';
108
+ $category = ! empty( $instance['category'] ) ? $instance['category'] : '';
109
+ $orderby = ! empty( $instance['orderby'] ) ? $instance['orderby'] : '';
110
+ $order = ! empty( $instance['order'] ) ? $instance['order'] : '';
111
+ $count = ! empty( $instance['count'] ) ? $instance['count'] : '6';
112
+ ?>
113
+ <p>
114
+ <label for="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>"><?php esc_attr_e( 'Title:', 'tutor' ); ?></label>
115
+ <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'title' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'title' ) ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>">
116
+ </p>
117
+
118
+ <p>
119
+ <label for="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>"><?php esc_attr_e( 'ID:', 'tutor' ); ?></label>
120
+ <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'id' ) ); ?>" name="<?php echo esc_attr( $this->get_field_name( 'id' ) ); ?>" type="text" value="<?php echo esc_attr( $id ); ?>"> <br />
121
+ <span style="color: #AAAAAA"><?php _e('Place single course id or comma (,) separated course ids', 'tutor'); ?></span>
122
+ </p>
123
+
124
+ <p>
125
+ <label for="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>"><?php esc_attr_e( 'Exclude IDS:', 'tutor' ); ?></label>
126
+ <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'exclude_ids' ) ); ?>" name="<?php echo esc_attr(
127
+ $this->get_field_name( 'exclude_ids' ) ); ?>" type="text" value="<?php echo esc_attr( $exclude_ids ); ?>"> <br />
128
+ <span style="color: #AAAAAA"><?php _e('Place comma (,) separated coruses ids which you like to exclude from the query', 'tutor');
129
+ ?></span>
130
+ </p>
131
+
132
+ <p>
133
+ <label for="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>"><?php esc_attr_e( 'Category:', 'tutor' ); ?></label>
134
+ <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'category' ) ); ?>" name="<?php echo esc_attr(
135
+ $this->get_field_name( 'category' ) ); ?>" type="text" value="<?php echo esc_attr( $category ); ?>"> <br />
136
+ <span style="color: #AAAAAA"><?php _e('Place comma (,) separated category ids', 'tutor');
137
+ ?></span>
138
+ </p>
139
+
140
+ <p>
141
+ <label for="<?php echo esc_attr( $this->get_field_id( 'orderby' ) ); ?>"><?php esc_attr_e( 'OrderBy', 'tutor' ); ?></label>
142
+
143
+ <select class="widefat" name="<?php echo esc_attr($this->get_field_name( 'orderby' ) ); ?>" >
144
+ <option value="ID" <?php selected('ID', $orderby) ?> >ID</option>
145
+ <option value="title" <?php selected('title', $orderby) ?> >title</option>
146
+ <option value="rand" <?php selected('rand', $orderby) ?> >rand</option>
147
+ <option value="date" <?php selected('date', $orderby) ?> >date</option>
148
+ <option value="menu_order" <?php selected('menu_order', $orderby) ?> >menu_order</option>
149
+ <option value="post__in" <?php selected('post__in', $orderby) ?> >post__in</option>
150
+ </select> <br />
151
+ </p>
152
+
153
+ <p>
154
+ <label for="<?php echo esc_attr( $this->get_field_id( 'order' ) ); ?>"><?php esc_attr_e( 'order', 'tutor' ); ?></label>
155
+
156
+ <select class="widefat" name="<?php echo esc_attr($this->get_field_name( 'order' ) ); ?>" >
157
+ <option value="DESC" <?php selected('DESC', $order) ?> >DESC</option>
158
+ <option value="ASC" <?php selected('ASC', $order) ?> >ASC</option>
159
+ </select> <br />
160
+ </p>
161
+
162
+ <p>
163
+ <label for="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>"><?php esc_attr_e( 'Count:', 'tutor' ); ?></label>
164
+ <input class="widefat" id="<?php echo esc_attr( $this->get_field_id( 'count' ) ); ?>" name="<?php echo esc_attr(
165
+ $this->get_field_name( 'count' ) ); ?>" type="number" value="<?php echo esc_attr( $count ); ?>"> <br />
166
+ <span style="color: #AAAAAA"><?php _e('Total results you like to show', 'tutor'); ?></span>
167
+ </p>
168
+
169
+ <?php
170
+ }
171
+
172
+ /**
173
+ * Sanitize widget form values as they are saved.
174
+ *
175
+ * @see WP_Widget::update()
176
+ *
177
+ * @param array $new_instance Values just sent to be saved.
178
+ * @param array $old_instance Previously saved values from database.
179
+ *
180
+ * @return array Updated safe values to be saved.
181
+ */
182
+ public function update( $new_instance, $old_instance ) {
183
+ $instance = array();
184
+ $instance['title'] = ( ! empty( $new_instance['title'] ) ) ? sanitize_text_field( $new_instance['title'] ) : '';
185
+ $instance['id'] = ( ! empty( $new_instance['id'] ) ) ? sanitize_text_field( $new_instance['id'] ) : '';
186
+ $instance['exclude_ids'] = ( ! empty( $new_instance['exclude_ids'] ) ) ? sanitize_text_field( $new_instance['exclude_ids'] ) : '';
187
+ $instance['category'] = ( ! empty( $new_instance['category'] ) ) ? sanitize_text_field( $new_instance['category'] ) : '';
188
+ $instance['orderby'] = ( ! empty( $new_instance['orderby'] ) ) ? sanitize_text_field( $new_instance['orderby'] ) : '';
189
+ $instance['order'] = ( ! empty( $new_instance['order'] ) ) ? sanitize_text_field( $new_instance['order'] ) : '';
190
+ $instance['count'] = ( ! empty( $new_instance['count'] ) ) ? sanitize_text_field( $new_instance['count'] ) : '';
191
+
192
+ return $instance;
193
+ }
194
+
195
+
196
+
197
+ }
classes/Shortcode.php CHANGED
@@ -17,6 +17,7 @@ class Shortcode {
17
  add_shortcode('tutor_student_registration_form', array($this, 'student_registration_form'));
18
  add_shortcode('tutor_dashboard', array($this, 'tutor_dashboard'));
19
  add_shortcode('tutor_instructor_registration_form', array($this, 'instructor_registration_form'));
 
20
  }
21
 
22
  /**
@@ -70,4 +71,62 @@ class Shortcode {
70
  return apply_filters( 'tutor_dashboard/student/index', ob_get_clean() );
71
  }
72
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
  }
17
  add_shortcode('tutor_student_registration_form', array($this, 'student_registration_form'));
18
  add_shortcode('tutor_dashboard', array($this, 'tutor_dashboard'));
19
  add_shortcode('tutor_instructor_registration_form', array($this, 'instructor_registration_form'));
20
+ add_shortcode('tutor_course', array($this, 'tutor_course'));
21
  }
22
 
23
  /**
71
  return apply_filters( 'tutor_dashboard/student/index', ob_get_clean() );
72
  }
73
 
74
+ /**
75
+ * @param $atts
76
+ *
77
+ * @return string
78
+ *
79
+ * Shortcode for getting course
80
+ */
81
+ public function tutor_course($atts){
82
+ $course_post_type = tutor()->course_post_type;
83
+
84
+ $a = shortcode_atts( array(
85
+ 'post_type' => $course_post_type,
86
+ 'post_status' => 'publish',
87
+
88
+ 'id' => '',
89
+ 'exclude_ids' => '',
90
+ 'category' => '',
91
+
92
+ 'orderby' => 'ID',
93
+ 'order' => 'DESC',
94
+ 'count' => '6',
95
+ ), $atts );
96
+
97
+ if ( ! empty($a['id'])){
98
+ $ids = (array) explode(',', $a['id']);
99
+ $a['post__in'] = $ids;
100
+ }
101
+
102
+ if ( ! empty($a['exclude_ids'])){
103
+ $exclude_ids = (array) explode(',', $a['exclude_ids']);
104
+ $a['post__not_in'] = $exclude_ids;
105
+ }
106
+ if ( ! empty($a['category'])){
107
+ $category = (array) explode(',', $a['category']);
108
+
109
+ $a['tax_query'] = array(
110
+ array(
111
+ 'taxonomy' => 'course-category',
112
+ 'field' => 'term_id',
113
+ 'terms' => $category,
114
+ 'operator' => 'IN',
115
+ ),
116
+ );
117
+ }
118
+ $a['posts_per_page'] = (int) $a['count'];
119
+
120
+ wp_reset_query();
121
+ query_posts($a);
122
+ ob_start();
123
+ tutor_load_template('shortcode.tutor-course');
124
+ $output = ob_get_clean();
125
+ wp_reset_query();
126
+
127
+ return $output;
128
+ }
129
+
130
+
131
+
132
  }
classes/Tutor.php CHANGED
@@ -46,6 +46,8 @@ final class Tutor{
46
  private $edd;
47
  private $withdraw;
48
 
 
 
49
  /**
50
  * @return null|Tutor
51
  *
@@ -66,6 +68,8 @@ final class Tutor{
66
  $this->url = plugin_dir_url(TUTOR_FILE);
67
  $this->basename = plugin_basename(TUTOR_FILE);
68
 
 
 
69
  /**
70
  * Include Files
71
  */
@@ -108,6 +112,8 @@ final class Tutor{
108
  $this->edd = new TutorEDD();
109
  $this->withdraw = new Withdraw();
110
 
 
 
111
  /**
112
  * Run Method
113
  * @since v.1.2.0
@@ -116,9 +122,9 @@ final class Tutor{
116
 
117
  do_action('tutor_loaded');
118
 
119
-
120
  add_action( 'init', array( $this, 'init_action' ) );
121
  }
 
122
  /**
123
  * @param $className
124
  *
@@ -207,6 +213,20 @@ final class Tutor{
207
  update_option('required_rewrite_flush', time());
208
  }
209
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
 
212
  //Run task on deactivation
@@ -214,6 +234,22 @@ final class Tutor{
214
  wp_clear_scheduled_hook('tutor_once_in_day_run_schedule');
215
  }
216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
217
  public function create_database(){
218
  global $wpdb;
219
 
46
  private $edd;
47
  private $withdraw;
48
 
49
+ private $course_widget;
50
+
51
  /**
52
  * @return null|Tutor
53
  *
68
  $this->url = plugin_dir_url(TUTOR_FILE);
69
  $this->basename = plugin_basename(TUTOR_FILE);
70
 
71
+ add_action('admin_init', array($this, 'tutor_course_post_type_update'));
72
+
73
  /**
74
  * Include Files
75
  */
112
  $this->edd = new TutorEDD();
113
  $this->withdraw = new Withdraw();
114
 
115
+ $this->course_widget = new Course_Widget();
116
+
117
  /**
118
  * Run Method
119
  * @since v.1.2.0
122
 
123
  do_action('tutor_loaded');
124
 
 
125
  add_action( 'init', array( $this, 'init_action' ) );
126
  }
127
+
128
  /**
129
  * @param $className
130
  *
213
  update_option('required_rewrite_flush', time());
214
  }
215
 
216
+ /**
217
+ * Backward Compatibility to < 1.3.1 for make course plural
218
+ */
219
+ if (version_compare(get_option('TUTOR_VERSION'), '1.3.1', '<')){
220
+ global $wpdb;
221
+
222
+ if ( ! get_option('is_course_post_type_updated')){
223
+ $wpdb->update($wpdb->posts, array('post_type' => 'courses'), array('post_type' => 'course'));
224
+ update_option('is_course_post_type_updated', true);
225
+ update_option('tutor_version', '1.3.1');
226
+ flush_rewrite_rules();
227
+ }
228
+ }
229
+
230
  }
231
 
232
  //Run task on deactivation
234
  wp_clear_scheduled_hook('tutor_once_in_day_run_schedule');
235
  }
236
 
237
+ public function tutor_course_post_type_update(){
238
+ /**
239
+ * Backward Compatibility to < 1.3.1 for make course plural
240
+ */
241
+ if (version_compare(get_option('TUTOR_VERSION'), '1.3.1', '<')){
242
+ global $wpdb;
243
+
244
+ if ( ! get_option('is_course_post_type_updated')){
245
+ $wpdb->update($wpdb->posts, array('post_type' => 'courses'), array('post_type' => 'course'));
246
+ update_option('is_course_post_type_updated', true);
247
+ update_option('tutor_version', '1.3.1');
248
+ flush_rewrite_rules();
249
+ }
250
+ }
251
+ }
252
+
253
  public function create_database(){
254
  global $wpdb;
255
 
classes/Utils.php CHANGED
@@ -793,6 +793,38 @@ class Utils {
793
  return $price;
794
  }
795
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
796
  /**
797
  * @param int $course_id
798
  *
@@ -4214,4 +4246,20 @@ class Utils {
4214
  return $query;
4215
  }
4216
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4217
  }
793
  return $price;
794
  }
795
 
796
+ /**
797
+ * @param int $course_id
798
+ *
799
+ * @return object
800
+ *
801
+ * Get raw course price and sale price of a course
802
+ * It could help you to calculate something
803
+ * Such as Calculate discount by regular price and sale price
804
+ *
805
+ * @since v.1.3.1
806
+ */
807
+ public function get_raw_course_price($course_id = 0){
808
+ $course_id = $this->get_post_id($course_id);
809
+
810
+ $prices = array(
811
+ 'regular_price' => 0,
812
+ 'sale_price' => 0,
813
+ );
814
+
815
+ if ($this->is_course_purchasable($course_id)){
816
+ if ($this->get_option('enable_course_sell_by_woocommerce') && $this->has_wc()){
817
+ $prices['regular_price']= get_post_meta($course_id, '_regular_price', true);
818
+ $prices['sale_price']= get_post_meta($course_id, '_sale_price', true);
819
+ }elseif ($this->get_option('enable_tutor_edd') && $this->has_edd() ){
820
+ $prices['regular_price']= get_post_meta($course_id, 'edd_price', true);
821
+ $prices['sale_price']= get_post_meta($course_id, 'edd_price', true);
822
+ }
823
+ }
824
+
825
+ return (object) $prices;
826
+ }
827
+
828
  /**
829
  * @param int $course_id
830
  *
4246
  return $query;
4247
  }
4248
 
4249
+ /**
4250
+ * @param null $status
4251
+ *
4252
+ * @return string
4253
+ *
4254
+ * Get status contact formatted for order
4255
+ *
4256
+ * @since v.1.3.1
4257
+ */
4258
+ public function order_status_context($status = null){
4259
+ $status = str_replace('wc-', '', $status);
4260
+ $status_name = ucwords(str_replace('-', ' ', $status));
4261
+
4262
+ return "<span class='label-order-status label-status-{$status}'>$status_name</span>";
4263
+ }
4264
+
4265
  }
includes/tutor-template-functions.php CHANGED
@@ -253,17 +253,43 @@ if ( ! function_exists('tutor_course_archive_filter_bar')) {
253
  }
254
  }
255
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  /**
257
  * Get the post thumbnail
258
  */
259
  if ( ! function_exists('get_tutor_course_thumbnail')) {
260
- function get_tutor_course_thumbnail($url = false) {
261
  $post_id = get_the_ID();
262
  $post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
263
 
264
  if ( $post_thumbnail_id ) {
265
-
266
- $size = 'post-thumbnail';
267
  $size = apply_filters( 'post_thumbnail_size', $size, $post_id );
268
  if ($url){
269
  return wp_get_attachment_image_url($post_thumbnail_id, $size);
@@ -285,12 +311,11 @@ if ( ! function_exists('get_tutor_course_thumbnail')) {
285
  * Get the course/post thumbnail src
286
  */
287
  if ( ! function_exists('get_tutor_course_thumbnail_src')) {
288
- function get_tutor_course_thumbnail_src() {
289
  $post_id = get_the_ID();
290
  $post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
291
 
292
  if ( $post_thumbnail_id ) {
293
- $size = 'post-thumbnail';
294
  $size = apply_filters( 'post_thumbnail_size', $size, $post_id );
295
  $src = wp_get_attachment_image_url( $post_thumbnail_id, $size, false );
296
  } else {
253
  }
254
  }
255
 
256
+ /**
257
+ *
258
+ * Get classes for widget loop single course wrap
259
+ *
260
+ * @param bool $echo
261
+ *
262
+ * @return string
263
+ *
264
+ * @since v.1.3.1
265
+ */
266
+ if( ! function_exists('tutor_widget_course_loop_classes')) {
267
+ function tutor_widget_course_loop_classes( $echo = true ) {
268
+
269
+ $classes = apply_filters( 'tutor_widget_course_loop_classes', array(
270
+ 'tutor-widget-course-loop',
271
+ 'tutor-widget-course',
272
+ 'tutor-widget-course-'.get_the_ID(),
273
+ ) );
274
+
275
+ $class = implode( ' ', $classes );
276
+ if ( $echo ) {
277
+ echo $class;
278
+ }
279
+
280
+ return $class;
281
+ }
282
+ }
283
+
284
  /**
285
  * Get the post thumbnail
286
  */
287
  if ( ! function_exists('get_tutor_course_thumbnail')) {
288
+ function get_tutor_course_thumbnail($size = 'post-thumbnail', $url = false) {
289
  $post_id = get_the_ID();
290
  $post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
291
 
292
  if ( $post_thumbnail_id ) {
 
 
293
  $size = apply_filters( 'post_thumbnail_size', $size, $post_id );
294
  if ($url){
295
  return wp_get_attachment_image_url($post_thumbnail_id, $size);
311
  * Get the course/post thumbnail src
312
  */
313
  if ( ! function_exists('get_tutor_course_thumbnail_src')) {
314
+ function get_tutor_course_thumbnail_src($size = 'post-thumbnail') {
315
  $post_id = get_the_ID();
316
  $post_thumbnail_id = (int) get_post_thumbnail_id( $post_id );
317
 
318
  if ( $post_thumbnail_id ) {
 
319
  $size = apply_filters( 'post_thumbnail_size', $size, $post_id );
320
  $src = wp_get_attachment_image_url( $post_thumbnail_id, $size, false );
321
  } else {
readme.txt CHANGED
@@ -5,7 +5,7 @@ Tags: lms, course, elearning, education, quiz, training, sell courses, courses,
5
  Requires at least: 4.5
6
  Tested up to: 5.2
7
  Requires PHP: 5.4.0
8
- Stable tag: 1.3.0
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
@@ -23,7 +23,7 @@ Get Tutor, the most advanced and powerful WordPress online course plugin.
23
 
24
  Create, customize, manage, and sell online courses by building a functional e-learning website with this free LMS plugin for WordPress.
25
 
26
- [Live Demo](https://demo.themeum.com/plugins/tutor/) || [Documentation](https://www.themeum.com/docs/tutor-introduction/) || [Tutor LMS Pro](https://www.themeum.com/product/tutor-lms/)
27
 
28
  = Features =
29
 
@@ -203,9 +203,24 @@ Tutor enables you to use any third party plugins without facing any compatibilit
203
  14. Quiz builder, questions
204
  15. Quiz builder, question edit and settings
205
  16. Course builder
 
206
 
207
  == Changelog ==
208
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  = 1.3.0 - 17 May, 2019 =
210
 
211
  * Added: Flash Msg ability to show flash msg in a different view or different action
5
  Requires at least: 4.5
6
  Tested up to: 5.2
7
  Requires PHP: 5.4.0
8
+ Stable tag: 1.3.1
9
  License: GPLv3
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
11
 
23
 
24
  Create, customize, manage, and sell online courses by building a functional e-learning website with this free LMS plugin for WordPress.
25
 
26
+ [Live Demo](https://demo.themeum.com/plugins/tutor/) || [Documentation](https://www.themeum.com/docs/tutor-introduction/) || [Tutor LMS Pro](https://www.themeum.com/product/tutor-lms/) || [Tutor LMS Themes](https://www.themeum.com/theme-category/tutor/)
27
 
28
  = Features =
29
 
203
  14. Quiz builder, questions
204
  15. Quiz builder, question edit and settings
205
  16. Course builder
206
+ 17. Tutor LMS Working Lifecycle
207
 
208
  == Changelog ==
209
 
210
+ = 1.3.1 - 22 May, 2019 =
211
+
212
+ * Added: status in the purchase history list
213
+ * Added: Shortcode for the coruse query, full shortcode `[tutor_course id="20,64" exclude_ids="567,332" category="18,19" order="desc" count="3"]`
214
+ * Added: a simple shortcode builder to build [tutor_course] Shortcode from classic editor
215
+ * Added: Tutor course widget to display course to sidebar
216
+ * Added: `utils()->get_raw_course_price($course_id)`, it will be return to your regular price and sale price as object
217
+ * Added: Course page edit by Pagebuilder integration which supports frontend editing
218
+ * Added: `$size = 'post-thumbnail',` Arguments at function `get_tutor_course_thumbnail()` And `get_tutor_course_thumbnail_src();`
219
+ * Fixed: Hide zero rating count in the course loop grid
220
+ * Fixed: some translation issue
221
+ * Changed: a template the_content(), reordered position in course single page
222
+ * Upgraded: course url upgrade to plural format, courses
223
+
224
  = 1.3.0 - 17 May, 2019 =
225
 
226
  * Added: Flash Msg ability to show flash msg in a different view or different action
templates/dashboard/purchase_history.php CHANGED
@@ -7,10 +7,11 @@ if (tutor_utils()->count($orders)){
7
  ?>
8
  <table>
9
  <tr>
10
- <th>ID</th>
11
- <th>Courses</th>
12
- <th>Amount</th>
13
- <th>Date</th>
 
14
  </tr>
15
  <?php
16
  foreach ($orders as $order){
@@ -29,7 +30,9 @@ if (tutor_utils()->count($orders)){
29
  ?>
30
  </td>
31
  <td><?php echo tutor_utils()->tutor_price($wc_order->get_total()); ?></td>
32
- <td>
 
 
33
  <?php echo date_i18n(get_option('date_format'), strtotime($order->post_date)) ?>
34
  </td>
35
  </tr>
7
  ?>
8
  <table>
9
  <tr>
10
+ <th><?php _e('ID', 'tutor'); ?></th>
11
+ <th><?php _e('Courses', 'tutor'); ?></th>
12
+ <th><?php _e('Amount', 'tutor'); ?></th>
13
+ <th><?php _e('Status', 'tutor'); ?></th>
14
+ <th><?php _e('Date', 'tutor'); ?></th>
15
  </tr>
16
  <?php
17
  foreach ($orders as $order){
30
  ?>
31
  </td>
32
  <td><?php echo tutor_utils()->tutor_price($wc_order->get_total()); ?></td>
33
+ <td><?php echo tutor_utils()->order_status_context($order->post_status); ?></td>
34
+
35
+ <td>
36
  <?php echo date_i18n(get_option('date_format'), strtotime($order->post_date)) ?>
37
  </td>
38
  </tr>
templates/loop/rating.php CHANGED
@@ -20,8 +20,10 @@ if ( ! defined( 'ABSPATH' ) ) {
20
  ?>
21
  <span class="tutor-rating-count">
22
  <?php
23
- echo $course_rating->rating_avg;
24
- echo '<i>('.$course_rating->rating_count.')</i>';
 
 
25
  ?>
26
  </span>
27
  </div>
20
  ?>
21
  <span class="tutor-rating-count">
22
  <?php
23
+ if ($course_rating->rating_avg > 0) {
24
+ echo apply_filters('tutor_course_rating_average', $course_rating->rating_avg);
25
+ echo '<i>(' . apply_filters('tutor_course_rating_count', $course_rating->rating_count) . ')</i>';
26
+ }
27
  ?>
28
  </span>
29
  </div>
templates/shortcode/tutor-course.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+
4
+ if ( have_posts() ) :
5
+ /* Start the Loop */
6
+
7
+ tutor_course_loop_start();
8
+
9
+ while ( have_posts() ) : the_post();
10
+ /**
11
+ * @hook tutor_course/archive/before_loop_course
12
+ * @type action
13
+ * Usage Idea, you may keep a loop within a wrap, such as bootstrap col
14
+ */
15
+ do_action('tutor_course/archive/before_loop_course');
16
+
17
+ tutor_load_template('loop.course');
18
+
19
+ /**
20
+ * @hook tutor_course/archive/after_loop_course
21
+ * @type action
22
+ * Usage Idea, If you start any div before course loop, you can end it here, such as </div>
23
+ */
24
+ do_action('tutor_course/archive/after_loop_course');
25
+ endwhile;
26
+
27
+ tutor_course_loop_end();
28
+
29
+ endif;
templates/single-course-enrolled-overview.php CHANGED
@@ -19,7 +19,6 @@ do_action('tutor_course/single/enrolled/before/wrap');
19
  <div class="tutor-col-8">
20
  <?php tutor_course_enrolled_lead_info(); ?>
21
  <?php tutor_course_enrolled_nav(); ?>
22
- <?php tutor_course_content(); ?>
23
  <?php get_tutor_posts_attachments(); ?>
24
  </div>
25
  <div class="tutor-col-4">
19
  <div class="tutor-col-8">
20
  <?php tutor_course_enrolled_lead_info(); ?>
21
  <?php tutor_course_enrolled_nav(); ?>
 
22
  <?php get_tutor_posts_attachments(); ?>
23
  </div>
24
  <div class="tutor-col-4">
templates/single-course-enrolled.php CHANGED
@@ -10,7 +10,6 @@
10
 
11
  get_header();
12
 
13
-
14
  do_action('tutor_course/single/enrolled/before/wrap');
15
  ?>
16
 
@@ -20,6 +19,7 @@ do_action('tutor_course/single/enrolled/before/wrap');
20
  <div class="tutor-col-8 tutor-col-md-100">
21
  <?php do_action('tutor_course/single/enrolled/before/inner-wrap'); ?>
22
  <?php tutor_course_enrolled_lead_info(); ?>
 
23
  <?php tutor_course_enrolled_nav(); ?>
24
  <?php tutor_course_topics(); ?>
25
  <?php tutor_course_instructors_html(); ?>
10
 
11
  get_header();
12
 
 
13
  do_action('tutor_course/single/enrolled/before/wrap');
14
  ?>
15
 
19
  <div class="tutor-col-8 tutor-col-md-100">
20
  <?php do_action('tutor_course/single/enrolled/before/inner-wrap'); ?>
21
  <?php tutor_course_enrolled_lead_info(); ?>
22
+ <?php tutor_course_content(); ?>
23
  <?php tutor_course_enrolled_nav(); ?>
24
  <?php tutor_course_topics(); ?>
25
  <?php tutor_course_instructors_html(); ?>
templates/single-course.php CHANGED
@@ -23,9 +23,9 @@ get_header();
23
  <?php do_action('tutor_course/single/before/inner-wrap'); ?>
24
 
25
  <?php tutor_course_lead_info(); ?>
26
- <?php tutor_course_benefits_html(); ?>
27
- <?php tutor_course_topics(); ?>
28
- <?php tutor_course_content(); ?>
29
  <?php tutor_course_instructors_html(); ?>
30
  <?php tutor_course_target_reviews_html(); ?>
31
 
23
  <?php do_action('tutor_course/single/before/inner-wrap'); ?>
24
 
25
  <?php tutor_course_lead_info(); ?>
26
+ <?php tutor_course_content(); ?>
27
+ <?php tutor_course_benefits_html(); ?>
28
+ <?php tutor_course_topics(); ?>
29
  <?php tutor_course_instructors_html(); ?>
30
  <?php tutor_course_target_reviews_html(); ?>
31
 
templates/single/course/course-content.php CHANGED
@@ -25,7 +25,10 @@ if ( empty($content)){
25
  </div>
26
 
27
  <div class="tutor-course-content-content">
28
- <?php echo wpautop($content); ?>
 
 
 
29
  </div>
30
  </div>
31
 
25
  </div>
26
 
27
  <div class="tutor-course-content-content">
28
+ <?php
29
+ the_content();
30
+ //echo wpautop($content);
31
+ ?>
32
  </div>
33
  </div>
34
 
templates/single/course/social_share.php CHANGED
@@ -12,7 +12,7 @@
12
  $share_config = array(
13
  'title' => get_the_title(),
14
  'text' => get_the_excerpt(),
15
- 'image' => get_tutor_course_thumbnail(true),
16
  );
17
  ?>
18
 
12
  $share_config = array(
13
  'title' => get_the_title(),
14
  'text' => get_the_excerpt(),
15
+ 'image' => get_tutor_course_thumbnail('post-thumbnail', true),
16
  );
17
  ?>
18
 
templates/widget/courses.php ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * The template for displaying Tutor Course Widget
4
+ *
5
+ * @package Tutor/Tempaltes
6
+ * @version 1.3.1
7
+ *
8
+ */
9
+
10
+ if ( have_posts() ) :
11
+ while ( have_posts() ) : the_post();
12
+ ?>
13
+ <div class="<?php echo tutor_widget_course_loop_classes(); ?>">
14
+ <?php tutor_load_template('loop.course'); ?>
15
+ </div>
16
+ <?php
17
+ endwhile;
18
+ endif;
tutor.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: Tutor LMS
4
  Plugin URI: https://www.themeum.com/product/tutor-lms/
5
  Description: Tutor is a complete solution for creating a Learning Management System in WordPress way. It can help you to create small to large scale online education site very conveniently. Power features like report, certificate, course preview, private file sharing make Tutor a robust plugin for any educational institutes.
6
  Author: Themeum
7
- Version: 1.3.0
8
  Author URI: http://themeum.com
9
  Requires at least: 4.5
10
  Tested up to: 5.2
@@ -17,7 +17,7 @@ if ( ! defined( 'ABSPATH' ) )
17
  /**
18
  * Defined the tutor main file
19
  */
20
- define('TUTOR_VERSION', '1.3.0');
21
  define('TUTOR_FILE', __FILE__);
22
 
23
 
@@ -47,7 +47,7 @@ if ( ! function_exists('tutor')) {
47
  'version' => TUTOR_VERSION,
48
  'nonce_action' => 'tutor_nonce_action',
49
  'nonce' => '_wpnonce',
50
- 'course_post_type' => apply_filters( 'tutor_course_post_type', 'course' ),
51
  'lesson_post_type' => apply_filters( 'tutor_lesson_post_type', 'lesson' ),
52
  'instructor_role' => apply_filters( 'tutor_instructor_role', 'tutor_instructor' ),
53
  'instructor_role_name' => apply_filters( 'tutor_instructor_role_name', __( 'Tutor Instructor', 'tutor' ) ),
4
  Plugin URI: https://www.themeum.com/product/tutor-lms/
5
  Description: Tutor is a complete solution for creating a Learning Management System in WordPress way. It can help you to create small to large scale online education site very conveniently. Power features like report, certificate, course preview, private file sharing make Tutor a robust plugin for any educational institutes.
6
  Author: Themeum
7
+ Version: 1.3.1
8
  Author URI: http://themeum.com
9
  Requires at least: 4.5
10
  Tested up to: 5.2
17
  /**
18
  * Defined the tutor main file
19
  */
20
+ define('TUTOR_VERSION', '1.3.1');
21
  define('TUTOR_FILE', __FILE__);
22
 
23
 
47
  'version' => TUTOR_VERSION,
48
  'nonce_action' => 'tutor_nonce_action',
49
  'nonce' => '_wpnonce',
50
+ 'course_post_type' => apply_filters( 'tutor_course_post_type', 'courses' ),
51
  'lesson_post_type' => apply_filters( 'tutor_lesson_post_type', 'lesson' ),
52
  'instructor_role' => apply_filters( 'tutor_instructor_role', 'tutor_instructor' ),
53
  'instructor_role_name' => apply_filters( 'tutor_instructor_role_name', __( 'Tutor Instructor', 'tutor' ) ),