PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / inc / custom-post-types / lesson.php

lesson.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at inc/custom-post-types/lesson.php

441 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Lesson_Post_Type
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 3.0.0
8 */
9
10 /**
11 * Prevent loading this file directly
12 */
13
14 use LearnPress\Databases\PostDB;
15 use LearnPress\Filters\LessonPostFilter;
16 use LearnPress\Filters\PostFilter;
17 use LearnPress\Models\CoursePostModel;
18 use LearnPress\Models\CourseSectionItemModel;
19 use LearnPress\Models\PostModel;
20 use LearnPress\Models\WPTables\LessonsTable;
21
22 defined( 'ABSPATH' ) || exit();
23
24 if ( ! class_exists( 'LP_Lesson_Post_Type' ) ) {
25
26 /**
27 * Class LP_Lesson_Post_Type
28 */
29 final class LP_Lesson_Post_Type extends LP_Abstract_Post_Type {
30 /**
31 * @var null
32 */
33 protected static $_instance = null;
34
35 /**
36 * @var string
37 */
38 protected $_post_type = LP_LESSON_CPT;
39
40 /**
41 * @var string
42 */
43 protected $_screen_list = 'edit-' . LP_LESSON_CPT;
44
45 /**
46 * LP_Lesson_Post_Type constructor.
47 *
48 * @param $post_type
49 */
50 public function __construct() {
51
52 // $this->add_map_method( 'before_delete', 'before_delete_lesson' );
53 // hide View Lesson link if not assigned to course
54
55 add_filter( 'views_edit-' . LP_LESSON_CPT, array( $this, 'views_pages' ), 10 );
56 add_filter( 'posts_pre_query', array( $this, 'posts_pre_query' ), 999, 2 );
57 // add_filter( 'posts_where_paged', array( $this, 'posts_where_paged' ), 10 );
58
59 parent::__construct();
60 }
61
62 /**
63 * Handle when save post.
64 *
65 * @param int $post_id
66 * @param WP_Post|null $post
67 * @param bool $is_update
68 *
69 * @return void
70 * @throws Exception
71 * @version 1.0.1
72 * @since 4.2.7.6
73 */
74 public function save_post( int $post_id, ?WP_Post $post = null, bool $is_update = false ) {
75 // Clear cache
76 $lpCache = new LP_Cache();
77 $lpCache->clear( "lessonPostModel/find/{$post_id}" );
78 $lpCache->clear( "lessonModel/find/{$post_id}" );
79
80 // Find courses have this lesson
81 $obj_course_ids = CourseSectionItemModel::get_courses_from_item_id( $post_id, LP_LESSON_CPT );
82 if ( ! empty( $obj_course_ids ) ) {
83 foreach ( $obj_course_ids as $obj_course_id ) {
84 $course_id = $obj_course_id->section_course_id;
85 $coursePostModel = CoursePostModel::find( $course_id, true );
86 if ( $coursePostModel ) {
87 $coursePostModel->save();
88 }
89 }
90 }
91 }
92
93 /**
94 * Declare class name of table list lessons.
95 *
96 * @param string $class_name
97 * @param array $args
98 *
99 * @return string
100 * @since 4.2.9.5
101 */
102 public function wp_list_table_class_name( $class_name, $args ) {
103 if ( $this->check_class_name_handle_table( $args['screen'] ) ) {
104 $class_name = LessonsTable::class;
105 }
106
107 return $class_name;
108 }
109
110 /**
111 * Query lp lessons in admin via Post DB
112 *
113 * @param array $posts
114 * @param WP_Query $wp_query
115 *
116 * @return array|WP_Query
117 * @since 4.4.8
118 * @version 1.0.0
119 */
120 public function posts_pre_query( $posts, $wp_query ) {
121 try {
122 if ( ! is_admin() ) {
123 return $posts;
124 }
125
126 // Check screen
127 $curren_screen = get_current_screen();
128 if ( ! $curren_screen || $curren_screen->id !== 'edit-' . LP_LESSON_CPT ) {
129 return $posts;
130 }
131
132 $post_type = $wp_query->get( 'post_type' );
133 if ( empty( $post_type ) || $post_type !== LP_LESSON_CPT ) {
134 return $posts;
135 }
136
137 $posts_per_page = get_user_option( "edit_{$post_type}_per_page", get_current_user_id() );
138 if ( empty( $posts_per_page ) ) {
139 $posts_per_page = 20;
140 }
141
142 $paged = max( 1, get_query_var( 'paged' ) );
143 $author = $wp_query->get( 'author' );
144 $status = $wp_query->get( 'post_status' );
145 $search = $wp_query->get( 's' );
146 $month = $wp_query->get( 'm' );
147 $orderby = LP_Request::get_param( 'orderby', '', 'key' );
148 $order = LP_Request::get_param( 'order', '', 'key' );
149 $preview = LP_Request::get_param( 'preview', '', 'key' );
150 $course_id = LP_Request::get_param( 'course', '', 'int' );
151
152 $filter = new LessonPostFilter();
153 $filter->page = $paged;
154 $filter->limit = $posts_per_page;
155 $filter->only_fields = [ 'p.ID', 'p.post_title', 'p.post_author', 'p.post_date', 'p.post_date_gmt' ];
156 $post_db = PostDB::getInstance();
157
158 if ( ! empty( $status ) ) {
159 $filter->post_status = array( $status );
160 }
161
162 if ( ! empty( $author ) ) {
163 $filter->post_author = absint( $author );
164 }
165
166 if ( ! empty( $search ) ) {
167 $filter->post_title = sanitize_text_field( wp_unslash( $search ) );
168 }
169
170 // Find lesson assign by course_id
171 if ( ! empty( $course_id ) ) {
172 $filter->join[] = "INNER JOIN {$post_db->tb_lp_section_items} si ON p.ID = si.item_id";
173 $filter->join[] = "INNER JOIN {$post_db->tb_lp_sections} st ON st.section_id = si.section_id";
174 $filter->where[] = $post_db->wpdb->prepare( 'AND st.section_course_id = %d', $course_id );
175 }
176
177 if ( ! empty( $month ) && is_numeric( $month ) && strlen( (string) $month ) === 6 ) {
178 $filter->where[] = $post_db->wpdb->prepare(
179 'AND YEAR(p.post_date) = %d AND MONTH(p.post_date) = %d',
180 substr( $month, 0, 4 ),
181 substr( $month, 4, 2 )
182 );
183 }
184
185 // Exclude status auto-draft
186 $filter->where[] = $post_db->wpdb->prepare( 'AND p.post_status != %s', PostModel::STATUS_AUTO_DRAFT );
187
188 // Join sections/courses when sorting by course-name
189 if ( $orderby === 'course-name' ) {
190 $filter->join[] = "LEFT JOIN {$post_db->wpdb->prefix}learnpress_section_items si ON p.ID = si.item_id";
191 $filter->join[] = "LEFT JOIN {$post_db->wpdb->prefix}learnpress_sections s ON s.section_id = si.section_id";
192 $filter->join[] = "LEFT JOIN {$post_db->wpdb->posts} c ON c.ID = s.section_course_id";
193 }
194
195 // Filter unassigned
196 if ( 'yes' === LP_Request::get_param( 'unassigned', '', 'key' ) ) {
197 $filter->where[] = "AND p.ID NOT IN(
198 SELECT si.item_id
199 FROM {$post_db->wpdb->learnpress_section_items} si
200 )";
201 }
202
203 // Filter preview.
204 // Non-preview lessons include those that do not have `_lp_preview` meta key.
205 if ( $preview ) {
206 $filter_preview = new LessonPostFilter();
207 $filter_preview->limit = -1;
208 $filter_preview->only_fields = [ PostFilter::COL_ID ];
209 $filter_preview->join[] = "INNER JOIN {$post_db->wpdb->postmeta} pm ON p.ID = pm.post_id";
210 $filter_preview->where[] = $post_db->wpdb->prepare(
211 'AND pm.meta_key = %s AND pm.meta_value = %s',
212 '_lp_preview',
213 'yes'
214 );
215 $filter_preview->return_string_query = true;
216
217 $preview_rows = $post_db->get_posts( $filter_preview );
218
219 $in = 'no' === $preview ? 'NOT' : '';
220 $filter->where[] = "AND p.ID {$in} IN({$preview_rows})";
221 }
222
223 if ( $orderby === 'course-name' ) {
224 $filter->order_by = 'c.post_title';
225 } elseif ( $orderby === 'title' ) {
226 $filter->order_by = 'p.post_title';
227 } elseif ( $orderby === 'author' ) {
228 $filter->order_by = 'p.post_author';
229 } elseif ( $orderby === 'date' ) {
230 $filter->order_by = 'p.post_date';
231 } else {
232 $filter->order_by = 'p.menu_order';
233 }
234
235 $filter->order = strtolower( $order ) === 'asc' ? 'ASC' : 'DESC';
236
237 // Get lp lessons
238 $total_rows = 0;
239 $lp_lessons = $post_db->get_posts( $filter, $total_rows );
240
241 $wp_query->post_count = count( $lp_lessons );
242 $wp_query->found_posts = $total_rows;
243 $posts = $lp_lessons;
244 } catch ( Throwable $e ) {
245 LP_Debug::error_log( $e );
246 }
247
248 return $posts;
249 }
250
251 /*public function posts_where_paged( $where ): string {
252 if ( ! $this->is_page_list_posts_on_backend() ) {
253 return $where;
254 }
255
256 global $wpdb;
257
258 if ( 'yes' === LP_Request::get( 'unassigned' ) ) {
259 $where .= $wpdb->prepare(
260 "
261 AND {$wpdb->posts}.ID NOT IN(
262 SELECT si.item_id
263 FROM {$wpdb->learnpress_section_items} si
264 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
265 WHERE p.post_type = %s
266 )
267 ",
268 LP_LESSON_CPT
269 );
270 }
271
272 $preview = LP_Request::get( 'preview' );
273
274 if ( $preview ) {
275 $clause = $wpdb->prepare(
276 "
277 SELECT ID
278 FROM {$wpdb->posts} p
279 INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = %s
280 WHERE pm.meta_value = %s
281 AND p.post_type = %s",
282 '_lp_preview',
283 'yes',
284 LP_LESSON_CPT
285 );
286
287 $in = '';
288 if ( 'no' === $preview ) {
289 $in = 'NOT';
290 }
291
292 $where .= " AND {$wpdb->posts}.ID {$in} IN({$clause})";
293 }
294
295 return $where;
296 }*/
297
298 /**
299 * Add filters to lesson view.
300 *
301 * @param array $views
302 *
303 * @return array
304 * @throws Exception
305 * @since 3.0.0
306 * @editor tungnx
307 * @version 1.0.2
308 */
309 public function views_pages( array $views ): array {
310 $count_unassigned_lesson = LP_Course_DB::getInstance()->get_total_item_unassigned( LP_LESSON_CPT );
311
312 if ( $count_unassigned_lesson > 0 ) {
313 $views['unassigned'] = sprintf(
314 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
315 admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&unassigned=yes' ),
316 isset( $_GET['unassigned'] ) ? 'current' : '',
317 __( 'Unassigned', 'learnpress' ),
318 $count_unassigned_lesson
319 );
320 }
321
322 $total_preview_items = LP_Lesson_DB::getInstance()->get_total_preview_items();
323 if ( $total_preview_items > 0 ) {
324 $views['lesson-preview'] = sprintf(
325 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
326 admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&preview=yes' ),
327 isset( $_GET['preview'] ) && $_GET['preview'] === 'yes' ? 'current' : '',
328 __( 'Preview', 'learnpress' ),
329 $total_preview_items
330 );
331 }
332
333 $total_no_preview_items = LP_Lesson_DB::getInstance()->get_total_no_preview_items( $total_preview_items );
334 if ( $total_no_preview_items > 0 ) {
335 $views['lesson-no-preview'] = sprintf(
336 '<a href="%s" class="%s">%s <span class="count">(%d)</span></a>',
337 admin_url( 'edit.php?post_type=' . LP_LESSON_CPT . '&preview=no' ),
338 isset( $_GET['preview'] ) && $_GET['preview'] === 'no' ? 'current' : '',
339 __( 'No Preview', 'learnpress' ),
340 $total_no_preview_items
341 );
342 }
343
344 return $views;
345 }
346
347 /**
348 * Register lesson post type.
349 */
350 public function args_register_post_type(): array {
351
352 return array(
353 'labels' => array(
354 'name' => esc_html__( 'Lessons', 'learnpress' ),
355 'menu_name' => esc_html__( 'Lessons', 'learnpress' ),
356 'singular_name' => esc_html__( 'Lesson', 'learnpress' ),
357 'add_new_item' => esc_html__( 'Add A New Lesson', 'learnpress' ),
358 'all_items' => esc_html__( 'Lessons', 'learnpress' ),
359 'view_item' => esc_html__( 'View Lesson', 'learnpress' ),
360 'add_new' => esc_html__( 'Add New', 'learnpress' ),
361 'edit_item' => esc_html__( 'Edit Lesson', 'learnpress' ),
362 'update_item' => esc_html__( 'Update Lesson', 'learnpress' ),
363 'search_items' => esc_html__( 'Search Lessons', 'learnpress' ),
364 'not_found' => esc_html__( 'No lesson found', 'learnpress' ),
365 'not_found_in_trash' => esc_html__( 'There was no lesson found in the trash', 'learnpress' ),
366 ),
367 'public' => true,
368 'query_var' => true,
369 'taxonomies' => array( 'lesson_tag' ),
370 'publicly_queryable' => true,
371 'show_ui' => true,
372 'has_archive' => false,
373 'capability_type' => LP_LESSON_CPT,
374 'map_meta_cap' => true,
375 'show_in_menu' => 'learn_press',
376 'show_in_admin_bar' => true,
377 'show_in_nav_menus' => true,
378 'show_in_rest' => learn_press_user_maybe_is_a_teacher(),
379 'supports' => array(
380 'title',
381 'editor',
382 'revisions',
383 'comments',
384 ),
385 'hierarchical' => false, // Lessons have no parent-child hierarchy.
386 'rewrite' => array(
387 'slug' => 'lessons',
388 'hierarchical' => true,
389 'with_front' => false,
390 ),
391 'exclude_from_search' => true,
392 );
393 }
394
395 /**
396 * Remove lesson form course items.
397 *
398 * @param int $post_id
399 *
400 * @since 3.0.0
401 */
402 /*public function before_delete( int $post_id = 0 ) {
403 $curd = new LP_Lesson_CURD();
404 $curd->delete( $post_id );
405 }*/
406
407 /**
408 * Lesson assigned view.
409 *
410 * @since 3.0.0
411 */
412 public function lesson_assigned() {
413 learn_press_admin_view( 'meta-boxes/course/assigned.php' );
414 }
415
416 public function meta_boxes() {
417 return array(
418 'lesson_assigned' => array(
419 'title' => esc_html__( 'Assigned', 'learnpress' ),
420 'callback' => array( $this, 'lesson_assigned' ),
421 'context' => 'side',
422 'priority' => 'high',
423 ),
424 );
425 }
426
427 /**
428 * @return LP_Lesson_Post_Type|null
429 */
430 public static function instance() {
431 if ( ! self::$_instance ) {
432 self::$_instance = new self();
433 }
434
435 return self::$_instance;
436 }
437 }
438
439 $lesson_post_type = LP_Lesson_Post_Type::instance();
440 }
441