1: <?php
2: if ( ! defined( 'ABSPATH' ) ) exit;
3:
4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Sensei_Messages {
15: public $token;
16: public $post_type;
17: public $meta_fields;
18:
19: 20: 21: 22:
23: public function __construct () {
24: $this->token = 'messages';
25: $this->post_type = 'sensei_message';
26: $this->meta_fields = array( 'sender', 'receiver' );
27:
28:
29: add_action( 'admin_menu', array( $this, 'add_menu_item' ), 40 );
30: add_action( 'add_meta_boxes', array( $this, 'add_meta_box' ), 10, 2 );
31: add_action( 'admin_menu', array( $this, 'remove_meta_box' ) );
32:
33:
34: add_action( 'init', array( $this, 'save_new_message' ), 1 );
35:
36:
37: add_action( 'comment_post', array( $this, 'message_reply_received' ), 10, 1 );
38:
39:
40: add_filter('comment_notification_recipients', array( $this, 'stop_wp_comment_emails' ), 20, 2 );
41:
42:
43: add_filter('comment_moderation_recipients', array( $this, 'stop_wp_comment_emails' ), 20, 2 );
44:
45:
46: add_action( 'save_post', array( $this, 'save_message' ) );
47:
48:
49: add_action( 'sensei_single_course_content_inside_before', array( $this, 'send_message_link' ), 35 );
50:
51:
52: add_action( 'sensei_single_lesson_content_inside_before', array( $this, 'send_message_link' ), 30, 2 );
53:
54:
55: add_action( 'sensei_single_quiz_questions_before', array( $this, 'send_message_link' ), 10, 2 );
56:
57:
58: add_action( 'template_redirect', array( $this, 'message_login' ), 10, 1 );
59: add_action( 'pre_get_posts', array( $this, 'message_list' ), 10, 1 );
60: add_filter( 'the_title', array( $this, 'message_title' ), 10, 2 );
61: add_filter( 'the_content', array( $this, 'message_content' ), 10, 1 );
62: add_filter( 'comments_array', array( $this, 'message_replies' ), 100, 1 );
63: add_filter( 'get_comments_number', array( $this, 'message_reply_count' ), 100, 2 );
64: add_filter( 'comments_open', array( $this, 'message_replies_open' ), 100, 2 );
65: }
66:
67: public function add_menu_item() {
68:
69: if( ! isset( Sensei()->settings->settings['messages_disable'] ) || ! Sensei()->settings->settings['messages_disable'] ) {
70: add_submenu_page( 'sensei', __( 'Messages', 'woothemes-sensei'), __( 'Messages', 'woothemes-sensei') , 'edit_courses', 'edit.php?post_type=sensei_message' );
71: }
72: }
73:
74: public function add_meta_box( $post_type, $post ) {
75:
76: if( ! $post_type == $this->post_type ) return;
77:
78: add_meta_box( $this->post_type . '-data', __( 'Message Information', 'woothemes-sensei' ), array( $this, 'meta_box_content' ), $this->post_type, 'normal', 'default' );
79:
80: }
81:
82: public function meta_box_content() {
83: global $post;
84:
85: $settings = array(
86: array(
87: 'id' => 'sender',
88: 'label' => __( 'Message sent by:', 'woothemes-sensei' ),
89: 'description' => __( 'The username of the learner who sent this message.', 'woothemes-sensei' ),
90: 'type' => 'text',
91: 'default' => '',
92: 'placeholder' => __( 'Learner username', 'woothemes-sensei' ),
93: ),
94: array(
95: 'id' => 'receiver',
96: 'label' => __( 'Message received by:', 'woothemes-sensei' ),
97: 'description' => __( 'The username of the teacher who received this message.', 'woothemes-sensei' ),
98: 'type' => 'text',
99: 'default' => '',
100: 'placeholder' => __( 'Teacher username', 'woothemes-sensei' ),
101: ),
102: );
103:
104: $message_posttype = get_post_meta( $post->ID, '_posttype', true );
105:
106: if( isset( $message_posttype ) && $message_posttype ) {
107:
108: $args = array(
109: 'post_type' => $message_posttype,
110: 'posts_per_page' => -1,
111: 'orderby' => 'name',
112: 'order' => 'ASC',
113: 'post_status' => 'publish',
114: );
115:
116: $posts = get_posts( $args );
117:
118: $post_options[0] = sprintf( __( 'Select %1$s', 'woothemes-sensei' ), $message_posttype );
119: foreach( $posts as $post_item ) {
120: $post_options[ $post_item->ID ] = $post_item->post_title;
121: }
122:
123: $settings[] = array(
124: 'id' => 'post',
125: 'label' => sprintf( __( 'Message from %1$s:', 'woothemes-sensei' ), $message_posttype ),
126: 'description' => sprintf( __( 'The %1$s to which this message relates.', 'woothemes-sensei' ), $message_posttype ),
127: 'type' => 'select',
128: 'default' => 0,
129: 'options' => $post_options,
130: );
131: }
132:
133: $html = Sensei()->admin->render_settings( $settings, $post->ID, 'message-info' );
134:
135: echo $html;
136: }
137:
138: public function save_message( $post_id = 0 ) {
139: global $post;
140:
141: if( $this->post_type != get_post_type() ) return;
142:
143: if( isset( $_POST['sender'] ) && $_POST['sender'] ) {
144: update_post_meta( $post_id, '_sender', $_POST['sender'] );
145: }
146:
147: if( isset( $_POST['receiver'] ) && $_POST['receiver'] ) {
148: update_post_meta( $post_id, '_receiver', $_POST['receiver'] );
149: }
150:
151: if( isset( $_POST['post'] ) && $_POST['post'] ) {
152: update_post_meta( $post_id, '_post', $_POST['post'] );
153: }
154:
155: remove_action( 'save_post', array( $this, 'save_message' ) );
156:
157: wp_update_post( array( 'ID' => $post_id, 'comment_status' => 'open' ) );
158:
159: add_action( 'save_post', array( $this, 'save_message' ) );
160: }
161:
162: public function send_message_link( $post_id = 0, $user_id = 0 ) {
163: global $post;
164:
165:
166: $allowed_post_types = array('lesson', 'course', 'quiz');
167: if ( ! in_array( get_post_type() , $allowed_post_types ) ) {
168:
169: return;
170:
171: }
172:
173: $html = '';
174:
175: if( ! isset( Sensei()->settings->settings['messages_disable'] ) || ! Sensei()->settings->settings['messages_disable'] ) {
176:
177: if( ! is_user_logged_in() ) return;
178:
179: if( isset( $_GET['contact'] ) ) {
180: $html .= $this->teacher_contact_form( $post );
181: } else {
182: $href = add_query_arg( array( 'contact' => $post->post_type ) );
183:
184: if( 'lesson' == $post->post_type ) {
185: $contact_button_text = __( 'Contact Lesson Teacher', 'woothemes-sensei' );
186: } elseif( 'course' == $post->post_type ) {
187: $contact_button_text = __( 'Contact Course Teacher', 'woothemes-sensei' );
188: }else{
189: $contact_button_text = __( 'Contact Teacher', 'woothemes-sensei' );
190: }
191:
192: $html .= '<p><a class="button send-message-button" href="' . esc_url($href) . '#private_message">' . $contact_button_text . '</a></p>';
193: }
194:
195: if( isset( $this->message_notice ) && isset( $this->message_notice['type'] ) && isset( $this->message_notice['notice'] ) ) {
196: $html .= '<div class="sensei-message ' . $this->message_notice['type'] . '">' . $this->message_notice['notice'] . '</div>';
197: }
198:
199: }
200:
201: echo $html;
202: }
203:
204: public function teacher_contact_form( $post ) {
205:
206: if( ! is_user_logged_in() ) return;
207:
208: global $current_user;
209: wp_get_current_user();
210:
211: $html = '';
212:
213: if( ! isset( $post->ID ) ) return $html;
214:
215:
216: $confirmation = '';
217: if( isset( $_GET[ 'send' ] ) && 'complete' == $_GET[ 'send' ] ) {
218:
219: $confirmation_message = __('Your private message has been sent.', 'woothemes-sensei');
220: $confirmation = '<div class="sensei-message tick">' . $confirmation_message . '</div>';
221:
222: }
223:
224: $html .= '<h3 id="private_message">' . __( 'Send Private Message', 'woothemes-sensei' ) . '</h3>';
225: $html .= '<p>';
226: $html .= $confirmation;
227: $html .= '</p>';
228: $html .= '<form name="contact-teacher" action="" method="post" class="contact-teacher">';
229: $html .= '<p class="form-row form-row-wide">';
230: $html .= '<textarea name="contact_message" placeholder="' . __( 'Enter your private message.', 'woothemes-sensei' ) . '"></textarea>';
231: $html .= '</p>';
232: $html .= '<p class="form-row">';
233: $html .= '<input type="hidden" name="post_id" value="' . $post->ID . '" />';
234: $html .= '<input type="hidden" name="sender_id" value="' . $current_user->ID . '" />';
235: $html .= '<input type="hidden" name="receiver_id" value="' . $post->post_author . '" />';
236: $html .= wp_nonce_field( 'message_teacher', 'sensei_message_teacher_nonce', true, false );
237: $html .= '<input type="submit" class="send_message" value="' . __( 'Send Message', 'woothemes-sensei' ) . '" />';
238: $html .= '</p>';
239: $html .= '<div class="fix"></div>';
240: $html .= '</form>';
241:
242: return $html;
243: }
244:
245: public function save_new_message() {
246:
247: if( ! isset( $_POST['sensei_message_teacher_nonce'] ) ) return;
248:
249: if( ! wp_verify_nonce( $_POST['sensei_message_teacher_nonce'], 'message_teacher' ) ) return;
250:
251: $message_id = $this->save_new_message_post( $_POST['sender_id'], $_POST['receiver_id'], $_POST['contact_message'], $_POST['post_id'] );
252:
253: }
254:
255: public function message_reply_received( $comment_id = 0 ) {
256:
257:
258: $comment = get_comment( $comment_id );
259:
260: if( is_null( $comment ) ) return;
261:
262:
263: $message = get_post( $comment->comment_post_ID );
264:
265: if( $message->post_type != $this->post_type ) return;
266:
267:
268: wp_set_comment_status( $comment_id, 'approve' );
269:
270: do_action( 'sensei_private_message_reply', $comment, $message );
271: }
272:
273: 274: 275: 276: 277: 278: 279: 280: 281: 282:
283: public function stop_wp_comment_emails( $emails , $comment_id ){
284:
285: $comment = get_comment( $comment_id );
286: if( isset( $comment->comment_post_ID ) &&
287: 'sensei_message' == get_post_type( $comment->comment_post_ID ) ){
288:
289:
290: $emails = array();
291:
292: }
293: return $emails;
294:
295: }
296:
297: 298: 299: 300: 301: 302: 303: 304:
305: private function save_new_message_post( $sender_id = 0, $receiver_id = 0, $message = '', $post_id = 0 ) {
306:
307: $message_id = false;
308:
309: if( $sender_id && $receiver_id && $message && $post_id ) {
310:
311: $title = wp_trim_words( $message, 8, '...' );
312:
313:
314: $message_data = array(
315: 'post_type' => $this->post_type,
316: 'post_title' => esc_html( $title ),
317: 'post_content' => esc_html( $message ),
318: 'post_status' => 'publish',
319: 'ping_status' => 'closed',
320: 'comment_status' => 'open',
321: 'post_excerpt' => '',
322: 'post_author' => intval( $sender_id )
323: );
324:
325:
326: $message_id = wp_insert_post( $message_data );
327:
328: if( ! is_wp_error( $message_id ) ) {
329:
330:
331: $sender = get_userdata( $sender_id );
332: add_post_meta( $message_id, '_sender', $sender->user_login );
333:
334:
335: $receiver = get_userdata( $receiver_id );
336: add_post_meta( $message_id, '_receiver', $receiver->user_login );
337:
338:
339: $post = get_post( $post_id );
340: add_post_meta( $message_id, '_posttype', $post->post_type );
341: add_post_meta( $message_id, '_post', $post->ID );
342:
343: do_action( 'sensei_new_private_message', $message_id );
344:
345: } else {
346:
347: $message_id = false;
348:
349: }
350: }
351:
352: return $message_id;
353: }
354:
355: 356: 357: 358: 359: 360:
361: private function view_message( $message_id, $user_id = 0) {
362:
363: if( ! is_user_logged_in() ) return false;
364:
365: if( $user_id == 0 ) {
366: global $current_user;
367: wp_get_current_user();
368: $user_login = $current_user->user_login;
369: }
370:
371:
372: $receiver = get_post_meta( $message_id, '_receiver', true );
373: $sender = get_post_meta( $message_id, '_sender', true );
374:
375:
376: if( in_array( $user_login, array( $receiver, $sender ) ) ) {
377: return true;
378: }
379:
380:
381: return false;
382: }
383:
384: 385: 386: 387:
388: public function remove_meta_box() {
389: remove_meta_box('commentstatusdiv', $this->post_type, 'normal');
390: }
391:
392: 393: 394: 395: 396: 397: 398: 399: 400: 401:
402:
403: public function message_login () {
404:
405: if ( is_user_logged_in() ) {
406:
407: return;
408: }
409:
410: $settings = Sensei()->settings->get_settings();
411: if( isset( $settings[ 'my_course_page' ] )
412: && 0 < intval( $settings[ 'my_course_page' ] ) ){
413:
414: $my_courses_page_id = $settings[ 'my_course_page' ];
415:
416: $my_courses_url = get_permalink($my_courses_page_id);
417:
418: }
419:
420: if ( is_single() && is_singular( $this->post_type )
421: || is_post_type_archive( $this->post_type ) ) {
422:
423: if ( isset($my_courses_url) ) {
424:
425: wp_redirect($my_courses_url, 303);
426: exit;
427: }
428:
429: else {
430:
431: wp_redirect(home_url('/wp-login.php'), 303);
432: exit;
433: }
434:
435: }
436: }
437: 438: 439: 440: 441:
442: public function message_list( $query ) {
443: global $current_user;
444:
445: if( is_admin() ) return;
446:
447: if( is_post_type_archive( $this->post_type ) && $query->is_main_query() ) {
448: wp_get_current_user();
449: $username = $current_user->user_login;
450:
451: $meta_query['relation'] = 'OR';
452:
453: $meta_query[] = array(
454: 'key' => '_sender',
455: 'value' => $username,
456: 'compare' => '='
457: );
458:
459: $meta_query[] = array(
460: 'key' => '_receiver',
461: 'value' => $username,
462: 'compare' => '='
463: );
464:
465: $query->set( 'meta_query', $meta_query );
466:
467: return;
468: }
469: }
470:
471: 472: 473: 474: 475: 476:
477: public function message_title( $title = '', $post_id = null ) {
478:
479: if( is_single() && is_singular( $this->post_type ) && in_the_loop() && get_post_type( $post_id ) == $this->post_type ) {
480: if( ! is_user_logged_in() || ! $this->view_message( $post_id ) ) {
481: $title = __( 'You are not allowed to view this message.', 'woothemes-sensei' );
482: }
483: }
484:
485: return $title;
486: }
487:
488: 489: 490: 491: 492:
493: public function message_content( $content ) {
494: global $post;
495:
496: if( is_single() && is_singular( $this->post_type ) && in_the_loop() ) {
497: if( ! is_user_logged_in() || ! $this->view_message( $post->ID ) ) {
498: $content = __( 'Please log in to view your messages.', 'woothemes-sensei' );
499: }
500: }
501:
502: return $content;
503: }
504:
505: 506: 507: 508: 509:
510: public function message_replies( $comments ) {
511: global $post;
512:
513: if( is_single() && is_singular( $this->post_type ) && in_the_loop() ) {
514: if( ! is_user_logged_in() || ! $this->view_message( $post->ID ) ) {
515: $comments = array();
516: }
517: }
518:
519: return $comments;
520: }
521:
522: 523: 524: 525: 526: 527:
528: public function message_reply_count( $count, $post_id ) {
529: global $post;
530:
531: if( is_single() && is_singular( $this->post_type ) && in_the_loop() ) {
532: if( ! is_user_logged_in() || ! $this->view_message( $post->ID ) ) {
533: $count = 0;
534: }
535: }
536:
537: return $count;
538: }
539:
540: 541: 542: 543: 544: 545:
546: public function message_replies_open( $open, $post_id ) {
547: global $post;
548:
549: if( is_single() && is_singular( $this->post_type ) && in_the_loop() ) {
550: if( ! is_user_logged_in() || ! $this->view_message( $post->ID ) ) {
551: $open = false;
552: }
553: }
554:
555: return $open;
556: }
557:
558: 559: 560: 561: 562:
563: public static function the_message_sent_by_title(){
564:
565: $sender_username = get_post_meta( get_the_ID() , '_sender', true );
566: if( $sender_username ) {
567:
568: $sender = get_user_by( 'login', $sender_username ); ?>
569:
570: <p class="message-meta">
571: <small>
572: <em>
573: <?php printf( __( 'Sent by %1$s on %2$s.', 'woothemes-sensei' ), $sender->display_name, get_the_date() ); ?>
574: </em>
575: </small>
576: </p>
577:
578: <?php }
579:
580: }
581:
582: 583: 584: 585: 586: 587:
588: public static function the_title() {
589:
590: global $post;
591:
592: $content_post_id = get_post_meta( $post->ID, '_post', true );
593: if( $content_post_id ) {
594: $title = sprintf( __( 'Re: %1$s', 'woothemes-sensei' ), '<a href="' . get_permalink( $content_post_id ) . '">' . get_the_title( $content_post_id ) . '</a>' );
595: } else {
596: $title = get_the_title( $post->ID );
597: }
598:
599: ?>
600: <header>
601:
602: <h1>
603:
604: <?php
605: 606: 607: 608: 609: 610: 611: 612:
613: echo apply_filters( 'sensei_single_title', $title, $post->post_type );
614: ?>
615:
616: </h1>
617:
618: </header>
619:
620: <?php
621:
622: }
623:
624: 625: 626: 627: 628: 629: 630: 631:
632: public static function the_archive_header( ){
633:
634: $html = '';
635: $html .= '<header class="archive-header"><h1>';
636: $html .= __( 'My Messages', 'woothemes-sensei' );
637: $html .= '</h1></header>';
638:
639: 640: 641: 642:
643: echo apply_filters( 'sensei_message_archive_title', $html );
644:
645: }
646:
647: 648: 649: 650: 651: 652:
653: public static function the_message_title( $message_post_id ){
654:
655: $content_post_id = get_post_meta( $message_post_id, '_post', true );
656:
657: if( $content_post_id ) {
658:
659: $title = sprintf( __( 'Re: %1$s', 'woothemes-sensei' ), get_the_title( $content_post_id ) );
660:
661: } else {
662:
663: $title = get_the_title( $message_post_id );
664:
665: }
666:
667: ?>
668: <h2>
669: <a href="<?php echo esc_url_raw( get_the_permalink( $message_post_id ) );?>">
670: <?php echo $title; ?>
671: </a>
672:
673: </h2>
674:
675: <?php
676: }
677:
678: 679: 680: 681: 682:
683: public static function the_message_sender( $message_post_id ){
684:
685: $sender_username = get_post_meta( $message_post_id, '_sender', true );
686: $sender = get_user_by( 'login', $sender_username );
687:
688: if( $sender_username && $sender instanceof WP_User ) {
689: $sender_display_name = sprintf( __( 'Sent by %1$s on %2$s.', 'woothemes-sensei' ), $sender->display_name, get_the_date() );
690: ?>
691: <p class="message-meta">
692: <small>
693: <em> <?php echo $sender_display_name; ?> </em>
694: </small>
695: </p>
696:
697: <?php
698: }
699:
700: }
701:
702: 703: 704: 705: 706:
707: public static function the_my_messages_link(){
708: if( ! Sensei()->settings->get('messages_disable') ) {
709: ?>
710: <p class="my-messages-link-container">
711: <a class="my-messages-link" href="<?php echo get_post_type_archive_link( 'sensei_message' ); ?>"
712: title="<?php _e( 'View & reply to private messages sent to your course & lesson teachers.', 'woothemes-sensei' ); ?>">
713: <?php _e( 'My Messages', 'woothemes-sensei' ); ?>
714: </a>
715: </p>
716: <?php
717: }
718: }
719:
720: }
721:
722: 723: 724: 725: 726:
727: class WooThemes_Sensei_Messages extends Sensei_Messages{}
728: