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 / abstract.php

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

1,155 lines 28.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Class LP_Abstract_Post_Type
5 *
6 * @author ThimPress
7 * @package LearnPress/Classes
8 * @version 1.0
9 */
10
11 use LearnPress\Models\CourseModel;
12 use LearnPress\Models\CourseSectionItemModel;
13 use LearnPress\Models\UserModel;
14 use LearnPress\TemplateHooks\UserTemplate;
15
16 defined( 'ABSPATH' ) || exit();
17
18 abstract class LP_Abstract_Post_Type {
19 /**
20 * Type of post
21 *
22 * @var string
23 */
24 protected $_post_type = '';
25
26 /**
27 * Screen list post type
28 * Ex: edit-{post_type}
29 *
30 * @var string
31 */
32 protected $_screen_list = '';
33
34 /**
35 * Metaboxes registered
36 *
37 * @var array
38 */
39 protected $_meta_boxes = array();
40
41 /**
42 * @var null
43 */
44 protected $_current_meta_box = null;
45
46 /**
47 * Columns display on list table
48 *
49 * @var array
50 */
51 protected $_columns = array();
52
53 /**
54 * Sortable columns
55 *
56 * @var array
57 */
58 protected $_sortable_columns = array();
59
60 /**
61 * Map default method to a new method
62 *
63 * @var array
64 */
65 // protected $_map_methods = array();
66
67 /**
68 * @var array
69 */
70 protected $_default_metas = array();
71
72 /**
73 * @var array
74 */
75 protected $_remove_features = array();
76
77 /**
78 * Constructor
79 *
80 * @param string
81 * @param mixed
82 */
83 public function __construct( $post_type = '', $args = '' ) {
84
85 if ( ! empty( $post_type ) ) {
86 $this->_post_type = $post_type;
87 }
88
89 $this->_do_register();
90
91 add_filter( 'wp_list_table_class_name', [ $this, 'wp_list_table_class_name' ], 10, 2 );
92 add_action( 'save_post', array( $this, '_do_save_post' ), - 1, 3 );
93 add_action( 'wp_after_insert_post', [ $this, 'wp_after_insert_post' ], - 1, 3 );
94 add_action( 'before_delete_post', array( $this, '_before_delete_post' ) );
95 add_action( 'deleted_post', array( $this, '_deleted_post' ) );
96 add_action( 'wp_trash_post', array( $this, '_before_trash_post' ) );
97 add_action( 'trashed_post', array( $this, '_trashed_post' ) );
98
99 //add_filter( 'manage_posts_columns', array( $this, '_manage_columns_head_title' ), 11, 2 );
100 //add_action( 'manage_posts_custom_column', array( $this, '_manage_column_value' ), 11, 2 );
101 add_filter( 'manage_edit-' . $this->_post_type . '_sortable_columns', array( $this, 'sortable_columns' ) );
102 add_filter( 'manage_' . $this->_post_type . '_posts_columns', array( $this, 'columns_head' ) );
103 add_filter( 'manage_' . $this->_post_type . '_posts_custom_column', array( $this, 'columns_content' ), 10, 2 );
104
105 add_filter( 'posts_fields', array( $this, '_posts_fields' ) );
106 add_filter( 'posts_join_paged', array( $this, '_posts_join_paged' ) );
107 add_filter( 'posts_where_paged', array( $this, '_posts_where_paged' ) );
108 add_filter( 'posts_orderby', array( $this, '_posts_orderby' ) );
109
110 // Show actions link on list post admin.
111 add_filter( 'post_row_actions', array( $this, '_post_row_actions' ), 10, 2 );
112
113 // New metabox: Nhamdv
114 add_action( 'add_meta_boxes', array( $this, 'render_meta_box' ), 0 );
115
116 // After update h5p and withdraw will remove it.
117 add_action( 'load-post.php', array( $this, 'add_meta_boxes' ), 0 );
118 add_action( 'load-post-new.php', array( $this, 'add_meta_boxes' ), 0 );
119 // End
120
121 // Comment by tungnx
122 // add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
123 // add_action( 'admin_enqueue_scripts', array( $this, 'admin_styles' ) );
124
125 // Comment by tungnx
126 // add_action( 'admin_footer-post.php', array( $this, 'print_js_template' ) );
127 // add_action( 'admin_footer-post-new.php', array( $this, 'print_js_template' ) );
128
129 // Comment by tungnx - not use
130 // add_action( 'pre_get_posts', array( $this, 'update_default_meta' ) );
131 add_action( 'admin_footer', array( $this, 'admin_footer_scripts' ) );
132
133 //add_filter( 'post_updated_messages', array( $this, 'updated_messages' ) );
134 add_action( 'admin_print_scripts', array( $this, 'remove_auto_save_script' ) );
135
136 // Remove wp-auth-check and heartbeat script on post type of LearnPress
137 add_action(
138 'admin_enqueue_scripts',
139 function ( $page ) {
140 if ( $page !== 'post.php' && $page !== 'post-new.php' ) {
141 return;
142 }
143
144 if ( get_post_type() !== $this->_post_type ) {
145 return;
146 }
147
148 wp_deregister_script( 'wp-auth-check' );
149 wp_deregister_script( 'heartbeat' );
150 },
151 1
152 );
153 }
154
155 /**
156 * This function is invoked along with 'init' action to register
157 * new post type with WP.
158 *
159 * @editor tungnx
160 * @since modify 4.1.0
161 */
162 public function _do_register() {
163 $args = $this->args_register_post_type();
164
165 /*
166 * Todo: This is function old, still has on some addons, so need replace "register" function to args_register_post_type
167 * When replace all will delete this function - long ago will delete, for some user didn't updated new addon version fix
168 */
169 if ( method_exists( $this, 'register' ) ) {
170 $args = $this->register();
171 }
172
173 if ( $args ) {
174 register_post_type( $this->_post_type, $args );
175
176 // Todo: tungnx review this code.
177 //flush_rewrite_rules();
178 }
179 }
180
181 /**
182 * Args to register custom post type.
183 *
184 * @return array
185 */
186 public function args_register_post_type(): array {
187 return array();
188 }
189
190 /**
191 * Check screen list post type
192 *
193 * @param WP_Screen|null $screen
194 *
195 * @return bool
196 */
197 public function check_class_name_handle_table( $screen ): bool {
198 if ( $screen instanceof WP_Screen
199 && $screen->id === $this->_screen_list ) {
200 return true;
201 }
202
203 return false;
204 }
205
206 /**
207 * Declare class name of table
208 *
209 * @param $class_name
210 * @param $args
211 *
212 * @return mixed
213 */
214 public function wp_list_table_class_name( $class_name, $args ) {
215 return $class_name;
216 }
217
218 /**
219 * Hook save post of WP
220 *
221 * In child-class use function save()
222 *
223 * @param int $post_id
224 * @param WP_Post|null|mixed $post
225 * @param bool $is_update
226 *
227 * @editor tungnx
228 * @since modify 4.0.9
229 * @version 4.0.3
230 */
231 final public function _do_save_post( int $post_id = 0, ?WP_Post $post = null, bool $is_update = false ) {
232 // Maybe remove
233 $this->maybe_remove_assigned( $post );
234
235 if ( ! $this->check_post( $post_id ) ) {
236 return;
237 }
238
239 $this->save( $post_id, $post );
240 $this->save_post( $post_id, $post, $is_update );
241 }
242
243 /**
244 * Function for child class handle when post has just saved
245 *
246 * @editor tungnx
247 * @docs Class post type extend need override this function if want to handle when save
248 */
249 public function save( int $post_id, WP_Post $post ) {
250 // Implement from child
251 }
252
253 /**
254 * Function for child class handle when post has just saved
255 * This function provides the argument `$update` to determine whether a post is updated or new.
256 * Replace for function save only has two args
257 *
258 * @param int $post_id
259 * @param WP_Post|null $post
260 * @param bool $is_update
261 *
262 * @since 4.2.6.9
263 * @version 1.0.1
264 */
265 public function save_post( int $post_id, ?WP_Post $post = null, bool $is_update = false ) {
266 // Implement from child
267 }
268
269 /**
270 * Callback hook 'wp_after_insert_post'
271 *
272 * @param $post_id
273 * @param $post
274 * @param $update
275 *
276 * @return void
277 * @since 4.2.6.9
278 * @version 1.0.1
279 */
280 final public function wp_after_insert_post( $post_id, $post, $update ) {
281 if ( ! $this->check_post( $post_id ) ) {
282 return;
283 }
284
285 $this->after_insert_post( $post_id, $post, $update );
286 }
287
288 /**
289 * Function for child class handle when post has just saved
290 *
291 * @param int $post_id
292 * @param WP_Post|null $post
293 * @param bool $update
294 */
295 public function after_insert_post( int $post_id, ?WP_Post $post = null, bool $update = false ) {
296 // Implement from child
297 }
298
299 /**
300 * Hook before delete post
301 * Only on receiver 1 param $post_id, can't get param $post - don't know why
302 *
303 * @param int $post_id
304 * @param WP_Post|null $post
305 *
306 * @editor tungnx
307 * @since modify 4.0.9
308 */
309 final public function _before_delete_post( int $post_id, ?WP_Post $post = null ) {
310 try {
311 // Todo: check is pages of LP
312 if ( 'page' === get_post_type( $post_id ) ) {
313 // Clear cache LP settings
314 $lp_settings_cache = new LP_Settings_Cache( true );
315 $lp_settings_cache->clean_lp_settings();
316 }
317
318 if ( ! $this->check_post( $post_id ) ) {
319 return;
320 }
321
322 $this->before_delete( $post_id );
323 } catch ( Throwable $e ) {
324 error_log( __METHOD__ . ': ' . $e->getMessage() );
325 }
326 }
327
328 /**
329 * Function for child class handle before post deleted
330 *
331 * @param int $post_id
332 *
333 * @editor tungnx
334 * @since modify 4.0.9
335 */
336 public function before_delete( int $post_id ) {
337 // Implement from child
338 }
339
340 /**
341 * Hook deleted post
342 *
343 * @param int $post_id
344 */
345 final public function _deleted_post( int $post_id ) {
346 $this->deleted_post( $post_id );
347 }
348
349 /**
350 * Function for child class handle when post has just deleted
351 *
352 * @editor tungnx
353 * @docs Class post type extend need override this function if want to handle when post deleted
354 */
355 public function deleted_post( int $post_id ) {
356 // Implement from child
357 }
358
359 protected $course_of_item_trashed = 0;
360
361 /**
362 * Hook before delete post
363 *
364 * @param int $post_id
365 *
366 * @author tungnx
367 * @since 4.1.6.9
368 * @version 1.0.1
369 */
370 final public function _before_trash_post( int $post_id ) {
371 if ( ! $this->check_post( $post_id ) ) {
372 return;
373 }
374
375 $this->before_trash_post( $post_id );
376 }
377
378 /**
379 * Before trash post
380 *
381 * @param int $post_id
382 *
383 * @return void
384 * @author tungnx
385 * @since 4.1.6.9
386 * @version 1.0.1
387 */
388 public function before_trash_post( int $post_id ) {
389 try {
390 // Case move item's course to trash
391 $course_item_types = CourseModel::item_types_support();
392 if ( ! in_array( get_post_type( $post_id ), $course_item_types ) ) {
393 return;
394 }
395
396 // Set course id of item when item assign on course is trashed
397 $course_of_item = LP_Course_DB::getInstance()->get_course_by_item_id( $post_id );
398 if ( $course_of_item ) {
399 $this->course_of_item_trashed = $course_of_item;
400 }
401 } catch ( Throwable $e ) {
402 error_log( $e->getMessage() );
403 }
404 }
405
406 /**
407 * Hook Trashed post
408 *
409 * @param int $post_id
410 *
411 * @return void
412 * @author tungnx
413 * @since 4.1.6.9
414 * @version 1.0.1
415 */
416 final public function _trashed_post( int $post_id ) {
417 if ( ! $this->check_post( $post_id ) ) {
418 return;
419 }
420
421 $this->trashed_post( $post_id );
422 }
423
424 /**
425 * Method handle Trashed post
426 *
427 * @param int $post_id
428 *
429 * @return void
430 * @since 4.1.6.9
431 * @version 1.0.0
432 * @author tungnx
433 */
434 public function trashed_post( int $post_id ) {
435 // Implement from child
436 // Check is item type of course
437 $course_item_types = learn_press_get_course_item_types();
438 if ( ! in_array( get_post_type( $post_id ), $course_item_types ) ) {
439 return;
440 }
441
442 if ( $this->course_of_item_trashed ) {
443 // Save course when item assign on course is trashed
444 $course_id = $this->course_of_item_trashed;
445 LP_Course_Post_Type::instance()->save_post( $course_id, null, true );
446 $this->course_of_item_trashed = 0;
447 }
448 }
449
450 public function column_instructor( $post_id = 0 ) {
451 $post = get_post( $post_id );
452 $user_id = $post->post_author;
453
454 $user = UserModel::find( $user_id, true );
455 if ( ! $user ) {
456 return;
457 }
458
459 $args = array(
460 'post_type' => $post->post_type,
461 'author' => $user_id,
462 );
463
464 $author_link = esc_url_raw( add_query_arg( $args, 'edit.php' ) );
465 $userTemplate = new UserTemplate();
466 echo sprintf(
467 '<span class="post-author">%s<a href="%s">%s</a></span>',
468 $userTemplate->html_avatar(
469 $user,
470 [
471 'width' => 32,
472 'height' => 32,
473 ]
474 ),
475 $author_link,
476 get_the_author()
477 );
478 }
479
480 /**
481 * Get column author
482 *
483 * @param $post
484 *
485 * @return void
486 * @since 4.2.9.5
487 * @version 1.0.0
488 */
489 public static function column_author( $post ) {
490 if ( ! $post instanceof WP_Post ) {
491 return;
492 }
493
494 $user_id = $post->post_author;
495 $userModel = UserModel::find( $user_id, true );
496 if ( ! $userModel ) {
497 return;
498 }
499
500 $args = array(
501 'post_type' => $post->post_type,
502 'author' => $user_id,
503 );
504
505 $author_link = esc_url_raw( add_query_arg( $args, 'edit.php' ) );
506 $userTemplate = new UserTemplate();
507 echo sprintf(
508 '<span class="post-author">%s<a href="%s">%s</a></span>',
509 $userTemplate->html_avatar(
510 $userModel,
511 [
512 'width' => 32,
513 'height' => 32,
514 ]
515 ),
516 $author_link,
517 $userModel->get_display_name()
518 );
519 }
520
521 public function get_post_type() {
522 $post_type = get_post_type();
523 if ( ! $post_type ) {
524 $post_type = LP_Request::get_param( 'post_type' );
525 }
526
527 return $post_type;
528 }
529
530 public function admin_footer_scripts() {
531
532 global $pagenow;
533
534 if ( $this->get_post_type() !== $this->_post_type ) {
535 return;
536 }
537
538 $user = learn_press_get_current_user();
539
540 if ( ! $user->is_admin() ) {
541 return;
542 }
543
544 // Comment by tungnx - not use on here, wrote on js
545 /*
546 if ( $pagenow === 'edit.php' ) {
547 $option = sprintf( '<option value="">%s</option>', __( 'Search by user', 'learnpress' ) );
548 $user = get_user_by( 'id', LP_Request::get_int( 'author' ) );
549
550 if ( $user ) {
551 $option = sprintf( '<option value="%d" selected="selected">%s</option>', $user->ID, $user->user_login );
552 }
553 }*/
554
555 // Todo: write this code on file js
556 if ( $pagenow === 'post.php' ) {
557 ?>
558 <script>
559 jQuery(function ($) {
560 var isAssigned = '<?php echo esc_js( $this->is_assigned() ); ?>',
561 $postStatus = $('#post_status'),
562 $message = $('<p class="learn-press-notice-assigned-item"></p>').html(isAssigned),
563 currentStatus = $postStatus.val();
564
565 (currentStatus === 'publish') && isAssigned && $postStatus.on('change', function () {
566 if (this.value !== 'publish') {
567 $message.insertBefore($('#post-status-select'));
568 } else {
569 $message.remove();
570 }
571 });
572
573 })
574 </script>
575 <?php
576 }
577 }
578
579 public function is_assigned() {
580 global $wpdb;
581 $post_type = $this->get_post_type();
582 if ( learn_press_is_support_course_item_type( $post_type ) ) {
583 $query = $wpdb->prepare(
584 "
585 SELECT s.section_course_id
586 FROM {$wpdb->learnpress_section_items} si
587 INNER JOIN {$wpdb->learnpress_sections} s ON s.section_id = si.section_id
588 INNER JOIN {$wpdb->posts} p ON p.ID = si.item_id
589 WHERE p.ID = %d
590 ",
591 get_the_ID()
592 );
593
594 $course_id = $wpdb->get_var( $query );
595 if ( $course_id ) {
596 return __( 'This item has already been assigned to the course. It will be removed from the course if it is not published.', 'learnpress' );
597 }
598 } elseif ( LP_QUESTION_CPT === $post_type ) {
599 $query = $wpdb->prepare(
600 "
601 SELECT p.ID
602 FROM {$wpdb->posts} p
603 INNER JOIN {$wpdb->learnpress_quiz_questions} qq ON p.ID = qq.quiz_id
604 WHERE qq.question_id = %d
605 ",
606 get_the_ID()
607 );
608
609 $quiz_id = $wpdb->get_var( $query );
610 if ( $quiz_id ) {
611 return __( 'This question has already been assigned to the quiz. It will be removed from the quiz if it is not published.', 'learnpress' );
612 }
613 }
614
615 return 0;
616 }
617
618 public function remove_auto_save_script() {
619 global $post;
620 if ( ! $post ) {
621 return;
622 }
623
624 if ( $this->check_post( $post->ID ) ) {
625 wp_dequeue_script( 'autosave' );
626 }
627 }
628
629 /**
630 * Maybe remove assigned item
631 *
632 * @param WP_Post $post
633 *
634 * @editor tungnx
635 * @todo Review and move to place correct
636 */
637 public function maybe_remove_assigned( $post = null ) {
638 global $wpdb;
639
640 if ( ! $post ) {
641 return;
642 }
643
644 $post_type = $post->post_type;
645 $post_status = $post->post_status;
646
647 // If we are updating question
648 if ( LP_QUESTION_CPT === $post_type ) {
649
650 // If question is not published then delete it from quizzes
651 if ( $post_status !== 'publish' ) {
652 $query = $wpdb->prepare(
653 "
654 DELETE FROM {$wpdb->learnpress_quiz_questions}
655 WHERE question_id = %d
656 ",
657 $post->ID
658 );
659 $wpdb->query( $query );
660 }
661 } elseif ( learn_press_is_support_course_item_type( $post_type ) ) {
662
663 // If item is not published then delete it from courses
664 if ( $post_status !== 'publish' ) {
665 $query = $wpdb->prepare(
666 "
667 DELETE FROM {$wpdb->learnpress_section_items}
668 WHERE item_id = %d
669 ",
670 $post->ID
671 );
672 $wpdb->query( $query );
673 }
674 }
675 }
676
677 /**
678 * @deprecated v4.2.9.4
679 */
680 protected function _get_quizzes_by_question( $question_id ) {
681 _deprecated_function( __METHOD__, '4.2.9.4' );
682 return [];
683
684 global $wpdb;
685 $query = $wpdb->prepare(
686 "
687 SELECT quiz_id
688 FROM {$wpdb->learnpress_quiz_questions}
689 WHERE question_id = %d
690 ",
691 $question_id
692 );
693
694 return $wpdb->get_col( $query );
695 }
696
697 /**
698 * @deprecated v4.2.9.4
699 */
700 protected function _get_courses_by_item( $item_id ) {
701 _deprecated_function( __METHOD__, '4.2.9.4' );
702 return [];
703
704 global $wpdb;
705 $query = $wpdb->prepare(
706 "
707 SELECT section_course_id
708 FROM {$wpdb->learnpress_sections} s
709 INNER JOIN {$wpdb->learnpress_section_items} si ON s.section_id = si.section_id
710 WHERE si.item_id = %d
711 ",
712 $item_id
713 );
714
715 return $wpdb->get_col( $query );
716 }
717
718 /**
719 * Ouput meta boxes.
720 *
721 * @param WP_Post $post
722 * @param mixed $box
723 */
724 public function _do_output_meta_box( $post, $box ) {
725 $callback = $this->_meta_boxes[ $box['id'] ][2];
726 if ( is_array( $callback ) ) {
727 if ( $callback[0] instanceof LP_Abstract_Post_Type ) {
728 if ( $callback[1] != __FUNCTION__ ) {
729 call_user_func_array( $callback, array( $post, $box ) );
730 }
731 } else {
732 call_user_func_array( $callback, array( $post, $box ) );
733 }
734 } else {
735 if ( is_callable( array( $this, $callback ) ) ) {
736 call_user_func_array( array( $this, $callback ), array( $post, $box ) );
737 } else {
738 call_user_func_array( $callback, array( $post, $box ) );
739 }
740 }
741 }
742
743 /**
744 * @editor tungnx
745 * @reason not use
746 */
747 /*
748 private function _is_archive() {
749 global $pagenow, $post_type;
750 if ( ! is_admin() || ( $pagenow != 'edit.php' ) || ( $this->_post_type != LP_Request::get_string( 'post_type' ) ) ) {
751 return false;
752 }
753
754 return true;
755 }*/
756
757 protected function _flush_cache() {
758 // LP_Hard_Cache::flush();
759 // wp_cache_flush();
760 }
761
762 public function _posts_fields( $fields ) {
763 if ( ! $this->_check_post() ) {
764 return $fields;
765 }
766
767 return $this->posts_fields( $fields );
768 }
769
770 public function _posts_join_paged( $join ) {
771 if ( ! $this->_check_post() ) {
772 return $join;
773 }
774
775 return $this->posts_join_paged( $join );
776 }
777
778 public function posts_join_paged( $join ) {
779 return $join;
780 }
781
782 final public function _posts_where_paged( $where ) {
783 if ( ! $this->_check_post() ) {
784 return $where;
785 }
786
787 return $this->posts_where_paged( $where );
788 }
789
790 public function posts_where_paged( $where ) {
791 return $where;
792 }
793
794 public function _posts_orderby( $orderby ) {
795 if ( ! $this->_check_post() ) {
796 return $orderby;
797 }
798
799 return $this->posts_orderby( $orderby );
800 }
801
802 public function posts_orderby( $orderby ) {
803 return $orderby;
804 }
805
806 /**
807 * Check post valid
808 *
809 * @return bool
810 */
811 public function _check_post(): bool {
812 global $pagenow, $post_type;
813
814 if ( ! is_admin() || ( ! in_array(
815 $pagenow,
816 array(
817 'edit.php',
818 'post.php',
819 )
820 ) ) || ( $this->_post_type != $post_type ) ) {
821 return false;
822 }
823
824 return true;
825 }
826
827 /**
828 * Check post is valid to handle
829 *
830 * @param int $post_id
831 *
832 * @return bool
833 * @since 4.1.6.9
834 * @version 1.0.1
835 */
836 public function check_post( int $post_id = 0 ): bool {
837 $can_save = true;
838
839 try {
840 $post = get_post( $post_id );
841 if ( ! $post ) {
842 return false;
843 }
844
845 if ( $this->_post_type !== $post->post_type ) {
846 //throw new Exception( 'Post type is invalid' );
847 return false;
848 }
849
850 if ( ! current_user_can( ADMIN_ROLE ) &&
851 get_current_user_id() !== (int) $post->post_author ) {
852 $can_save = false;
853 }
854
855 $can_save = apply_filters( 'lp/custom-post-type/can-save', $can_save, $post );
856 } catch ( Throwable $e ) {
857 $can_save = false;
858 }
859
860 return $can_save;
861 }
862
863 /**
864 * Check is page list posts valid
865 *
866 * @return bool
867 */
868 protected function is_page_list_posts_on_backend(): bool {
869 global $pagenow, $post_type;
870
871 if ( ! is_admin() || $pagenow != 'edit.php' || ( $this->_post_type != $post_type ) ) {
872 return false;
873 }
874
875 return true;
876 }
877
878 /**
879 * New Metabox instance
880 *
881 * @return array
882 * @author Nhamdv
883 */
884 public function meta_boxes() {
885 return array();
886 }
887
888 /**
889 * Render Metabox.
890 *
891 * @return void
892 * @author Nhamdv
893 */
894 public function render_meta_box() {
895 $add_meta_box = $this->meta_boxes();
896 $metaboxes = ! empty( $add_meta_box ) && is_array( $add_meta_box ) ? $add_meta_box : array();
897
898 $metaboxes = apply_filters( 'learnpress/custom-post-type/add-meta-box', $metaboxes, $this->_post_type );
899
900 if ( ! empty( $metaboxes ) ) {
901 foreach ( $metaboxes as $metabox_id => $metabox ) {
902 if ( isset( $metabox['callback'] ) ) {
903 add_meta_box( $metabox_id, $metabox['title'] ?? esc_html__( 'Unknown', 'learnpress' ), $metabox['callback'], $metabox['post_type'] ?? $this->_post_type, $metabox['context'] ?? 'normal', $metabox['priority'] ?? 'high' );
904 }
905 }
906 }
907 }
908
909 // Todo: after update metabox in h5p and withdraw will remove this function
910 public function add_meta_box( $id, $title, $callback = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
911 $this->_meta_boxes[ $id ] = func_get_args();
912
913 return $this;
914 }
915
916 // Todo: after update metabox in h5p and withdraw will remove this function
917 public function add_meta_boxes() {
918 if ( $this->_post_type != learn_press_get_requested_post_type() ) {
919 return;
920 }
921
922 do_action( 'learn_press_add_meta_boxes', $this->_post_type, $this );
923 do_action( "learn_press_{$this->_post_type}_add_meta_boxes", $this );
924
925 if ( ! $this->_meta_boxes ) {
926 return;
927 }
928
929 foreach ( $this->_meta_boxes as $k => $meta_box ) {
930 $size = sizeof( $meta_box );
931
932 if ( ( $size == 2 ) || ( $size == 3 && ! $meta_box[2] ) ) {
933 $func = 'output_' . preg_replace( '/[-]+/', '_', $meta_box[0] );
934 $meta_box[2] = array( $this, $func );
935 }
936 array_splice( $meta_box, 3, 0, array( $this->_post_type ) );
937 $this->_meta_boxes[ $k ] = $meta_box;
938
939 $meta_box[2] = array( $this, '_do_output_meta_box' );
940 call_user_func_array( 'add_meta_box', $meta_box );
941 }
942 }
943
944 /**
945 * Filter item by the course selected.
946 *
947 * @return bool|int
948 * @Todo move to course LP_Course_Post_Type
949 * @since 3.0.7
950 */
951 protected function _filter_items_by_course() {
952 $course_id = ! empty( $_REQUEST['course'] ) ? absint( $_REQUEST['course'] ) : false;
953
954 if ( ! $course_id ) {
955 global $post_type;
956 if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
957 $course_id = false;
958 }
959 }
960
961 return $course_id;
962 }
963
964 /**
965 * @return mixed
966 * @Todo move to course LP_Course_Post_Type
967 */
968 protected function _get_course_column_title() {
969 global $post_type;
970
971 if ( ! learn_press_is_support_course_item_type( $post_type ) ) {
972 return false;
973 }
974
975 $title = esc_html__( 'Course', 'learnpress' );
976 $course_id = $this->_filter_items_by_course();
977
978 if ( $course_id ) {
979 $course = learn_press_get_course( $course_id );
980
981 if ( $course ) {
982 $count = $course->count_items( $this->_post_type );
983 $post_object = get_post_type_object( $post_type );
984 $title = sprintf( _n( 'Course (%1$d %2$s)', 'Course (%1$d %2$s)', $count, 'learnpress' ), $count, $count > 1 ? $post_object->label : $post_object->labels->singular_name );
985 }
986 }
987
988 return $title;
989 }
990
991 /**
992 * Get course that the items is contained.
993 *
994 * @param $post_id
995 */
996 protected function get_courses_of_item( $post_id ) {
997 $courses = CourseSectionItemModel::get_courses_from_item_id(
998 $post_id, get_post_type( $post_id )
999 );
1000 if ( $courses ) {
1001 foreach ( $courses as $course ) {
1002 $course_id = $course->section_course_id;
1003 echo '<div><a href="' . esc_url_raw( remove_query_arg( 'orderby', add_query_arg( array( 'course' => $course_id ) ) ) ) . '">' . get_the_title( $course_id ) . '</a>';
1004 echo '<div class="row-actions">';
1005 printf( '<a href="%s">%s</a>', admin_url( sprintf( 'post.php?post=%d&action=edit', $course_id ) ), __( 'Edit', 'learnpress' ) );
1006 echo '&nbsp;|&nbsp;';
1007 printf( '<a href="%s">%s</a>', get_the_permalink( $course_id ), __( 'View', 'learnpress' ) );
1008
1009 if ( $this->_filter_items_by_course() ) {
1010 echo '&nbsp;|&nbsp;';
1011 printf(
1012 '<a href="%s">%s</a>',
1013 esc_url_raw( remove_query_arg( array( 'course', 'orderby' ) ) ),
1014 __( 'Remove Filter', 'learnpress' )
1015 );
1016 }
1017 echo '</div></div>';
1018 }
1019 } else {
1020 _e( 'Not assigned yet', 'learnpress' );
1021 }
1022 }
1023
1024 /**
1025 * @param string $fields
1026 *
1027 * @return mixed
1028 */
1029 public function posts_fields( $fields ) {
1030 return $fields;
1031 }
1032
1033 /**
1034 * Get sortable columns for list table
1035 *
1036 * @return mixed
1037 */
1038 public function sortable_columns( $columns ) {
1039 return $columns;
1040 }
1041
1042 public function columns_head( $columns ) {
1043 return $columns;
1044 }
1045
1046 public function columns_content( $column, $post_id = 0 ) {
1047 // Implement from child
1048 }
1049
1050 /**
1051 * Get string for searching
1052 *
1053 * @return string
1054 */
1055 protected function get_search(): string {
1056 return LP_Request::get( 's' );
1057 }
1058
1059 /**
1060 * @return string
1061 */
1062 protected function get_order_sort(): string {
1063 return strtolower( LP_Request::get_param( 'order' ) ) === 'desc' ? 'DESC' : 'ASC';
1064 }
1065
1066 /**
1067 * @return mixed
1068 */
1069 protected function get_order_by(): string {
1070 return LP_Request::get_param( 'orderby' );
1071 }
1072
1073 /**
1074 * Show actions on list post
1075 *
1076 * @param string[] $actions
1077 * @param WP_Post $post
1078 *
1079 * @return array|false|mixed
1080 */
1081 public function _post_row_actions( $actions, $post ) {
1082 if ( ! $this->_check_post() ) {
1083 return $actions;
1084 }
1085
1086 return $this->row_actions( $actions, $post );
1087 }
1088
1089 public function row_actions( $actions, $post ) {
1090 return $actions;
1091 }
1092
1093 /**
1094 * @deprecated 4.1.6.9
1095 */
1096 public function updated_messages( $messages ) {
1097 $post = get_post();
1098 $post_type = get_post_type( $post );
1099 $post_type_object = get_post_type_object( $this->_post_type );
1100 if ( $this->_post_type !== $post_type ) {
1101 return $messages;
1102 }
1103 $messages[ $this->_post_type ] = array(
1104 0 => '', // Unused. Messages start at index 1.
1105 1 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'updated.', 'learnpress' ) ),
1106 2 => __( 'Custom field updated.', 'learnpress' ),
1107 3 => __( 'Custom field deleted.', 'learnpress' ),
1108 4 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'updated.', 'learnpress' ) ),
1109 /* translators: %s: date and time of the revision */
1110 5 => isset( $_GET['revision'] ) ? sprintf( __( 'The lesson has been restored to revision from %s', 'learnpress' ), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
1111 6 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'published.', 'learnpress' ) ),
1112 7 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'saved.', 'learnpress' ) ),
1113 8 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'submitted.', 'learnpress' ) ),
1114 9 => sprintf(
1115 sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'scheduled for: <strong>%1$s</strong>.', 'learnpress' ) ),
1116 // translators: Publish box date format, see http://php.net/date
1117 date_i18n( __( 'M j, Y @ G:i', 'learnpress' ), strtotime( $post->post_date ) )
1118 ),
1119 10 => sprintf( '%s %s', $post_type_object->labels->singular_name, __( 'draft updated.', 'learnpress' ) ),
1120 );
1121
1122 if ( $post_type_object->publicly_queryable ) {
1123 $permalink = get_permalink( $post->ID );
1124
1125 $view_link = sprintf( ' <a href="%s">%s</a>', esc_url_raw( $permalink ), sprintf( '%s %s', __( 'View', 'learnpress' ), $post_type_object->labels->singular_name ) );
1126 switch ( $this->_post_type ) {
1127 case LP_LESSON_CPT:
1128 case LP_QUIZ_CPT:
1129 //$view_link = learn_press_get_item_course_id( $post->ID, $post->post_type ) ? $view_link : '';
1130 $view_link = LP_Course_DB::getInstance()->get_course_by_item_id( $post->ID ) ? $view_link : '';
1131 break;
1132 case LP_ORDER_CPT:
1133 $order = learn_press_get_order( $post->ID );
1134 $view_link = $order->get_view_order_url();
1135 $view_link = sprintf( ' <a href="%s">%s</a>', esc_url_raw( $view_link ), sprintf( '%s %s', __( 'View', 'learnpress' ), $post_type_object->labels->singular_name ) );
1136 break;
1137 case LP_QUESTION_CPT:
1138 $view_link = '';
1139 break;
1140 }
1141 $messages[ $this->_post_type ][1] .= $view_link;
1142 $messages[ $this->_post_type ][6] .= $view_link;
1143 $messages[ $this->_post_type ][9] .= $view_link;
1144
1145 $preview_permalink = learn_press_get_preview_url( $post->ID );
1146
1147 $preview_link = sprintf( ' <a target="_blank" href="%s">%s</a>', esc_url_raw( $preview_permalink ), sprintf( '%s %s', __( 'Preview', 'learnpress' ), $post_type_object->labels->singular_name ) );
1148 $messages[ $this->_post_type ][8] .= $preview_link;
1149 $messages[ $this->_post_type ][10] .= $preview_link;
1150 }
1151
1152 return $messages;
1153 }
1154 }
1155