1: <?php
2: if ( ! defined( 'ABSPATH' ) ) exit;
3:
4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
14: class Sensei_Learner_Management {
15:
16: public $name;
17: public $file;
18: public $page_slug;
19:
20: 21: 22: 23: 24:
25: public function __construct ( $file ) {
26: $this->name = __( 'Learner Management', 'woothemes-sensei' );;
27: $this->file = $file;
28: $this->page_slug = 'sensei_learners';
29:
30:
31: if ( is_admin() ) {
32: add_action( 'admin_menu', array( $this, 'learners_admin_menu' ), 30);
33: add_action( 'learners_wrapper_container', array( $this, 'wrapper_container' ) );
34: if ( isset( $_GET['page'] ) && ( $_GET['page'] == $this->page_slug ) ) {
35: add_action( 'admin_print_scripts', array( $this, 'enqueue_scripts' ) );
36: add_action( 'admin_print_styles', array( $this, 'enqueue_styles' ) );
37: }
38:
39: add_action( 'admin_init', array( $this, 'add_new_learners' ) );
40:
41: add_action( 'admin_notices', array( $this, 'add_learner_notices' ) );
42: }
43:
44:
45: if ( is_admin() ) {
46: add_action( 'wp_ajax_get_redirect_url_learners', array( $this, 'get_redirect_url' ) );
47: add_action( 'wp_ajax_remove_user_from_post', array( $this, 'remove_user_from_post' ) );
48: add_action( 'wp_ajax_sensei_json_search_users', array( $this, 'json_search_users' ) );
49: }
50: }
51:
52: 53: 54: 55: 56: 57:
58: public function learners_admin_menu() {
59: global $menu;
60:
61: if ( current_user_can( 'manage_sensei_grades' ) ) {
62: $learners_page = add_submenu_page( 'sensei', $this->name, $this->name, 'manage_sensei_grades', $this->page_slug, array( $this, 'learners_page' ) );
63: }
64:
65: }
66:
67: 68: 69: 70: 71: 72: 73: 74:
75: public function enqueue_scripts () {
76:
77: $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
78:
79:
80: wp_enqueue_script( 'sensei-learners-general',
81: Sensei()->plugin_url . 'assets/js/learners-general' . $suffix . '.js',
82: array('jquery','sensei-core-select2','sensei-chosen-ajax' ), Sensei()->version, true );
83:
84: $data = array(
85: 'remove_generic_confirm' => __( 'Are you sure you want to remove this user?', 'woothemes-sensei' ),
86: 'remove_from_lesson_confirm' => __( 'Are you sure you want to remove the user from this lesson?', 'woothemes-sensei' ),
87: 'remove_from_course_confirm' => __( 'Are you sure you want to remove the user from this course?', 'woothemes-sensei' ),
88: 'remove_user_from_post_nonce' => wp_create_nonce( 'remove_user_from_post_nonce' ),
89: 'search_users_nonce' => wp_create_nonce( 'search-users' ),
90: 'selectplaceholder'=> __( 'Select Learner', 'woothemes-sensei' )
91: );
92:
93: wp_localize_script( 'sensei-learners-general', 'woo_learners_general_data', $data );
94:
95: }
96:
97: 98: 99: 100: 101: 102: 103: 104:
105: public function enqueue_styles () {
106:
107: wp_enqueue_style( 'woothemes-sensei-admin' );
108:
109: }
110:
111: 112: 113: 114: 115:
116: public function load_data_table_files() {
117:
118:
119: $classes_to_load = array( 'list-table',
120: 'learners-main',
121: );
122: foreach ( $classes_to_load as $class_file ) {
123: Sensei()->load_class( $class_file );
124: }
125:
126: }
127:
128: 129: 130: 131: 132: 133: 134: 135:
136: public function load_data_object( $name = '', $data = 0, $optional_data = null ) {
137:
138: $object_name = 'WooThemes_Sensei_Learners_' . $name;
139: if ( is_null($optional_data) ) {
140: $sensei_learners_object = new $object_name( $data );
141: } else {
142: $sensei_learners_object = new $object_name( $data, $optional_data );
143: }
144: if ( 'Main' == $name ) {
145: $sensei_learners_object->prepare_items();
146: }
147: return $sensei_learners_object;
148: }
149:
150: 151: 152: 153: 154: 155:
156: public function learners_page() {
157:
158:
159: $course_id = 0;
160: $lesson_id = 0;
161: if( isset( $_GET['course_id'] ) ) {
162: $course_id = intval( $_GET['course_id'] );
163: }
164: if( isset( $_GET['lesson_id'] ) ) {
165: $lesson_id = intval( $_GET['lesson_id'] );
166: }
167: $sensei_learners_main = $this->load_data_object( 'Main', $course_id, $lesson_id );
168:
169: do_action( 'learners_before_container' );
170: do_action( 'learners_wrapper_container', 'top' );
171: $this->learners_headers();
172: ?>
173: <div id="poststuff" class="sensei-learners-wrap">
174: <div class="sensei-learners-main">
175: <?php $sensei_learners_main->display(); ?>
176: </div>
177: <div class="sensei-learners-extra">
178: <?php do_action( 'sensei_learners_extra' ); ?>
179: </div>
180: </div>
181: <?php
182: do_action( 'learners_wrapper_container', 'bottom' );
183: do_action( 'learners_after_container' );
184: }
185:
186: 187: 188: 189: 190: 191:
192: public function learners_headers( $args = array( 'nav' => 'default' ) ) {
193:
194: $function = 'learners_' . $args['nav'] . '_nav';
195: $this->$function();
196: do_action( 'sensei_learners_after_headers' );
197:
198: }
199:
200: 201: 202: 203: 204: 205:
206: public function wrapper_container( $which ) {
207: if ( 'top' == $which ) {
208: ?><div id="woothemes-sensei" class="wrap woothemes-sensei"><?php
209: } elseif ( 'bottom' == $which ) {
210: ?></div><!--/
211: }
212: }
213:
214: 215: 216: 217: 218:
219: public function learners_default_nav() {
220: $title = $this->name;
221: if ( isset( $_GET['course_id'] ) ) {
222: $course_id = intval( $_GET['course_id'] );
223: $url = add_query_arg( array( 'page' => $this->page_slug, 'course_id' => $course_id, 'view' => 'learners' ), admin_url( 'admin.php' ) );
224: $title .= sprintf( ' <span class="course-title">> <a href="%s">%s</a></span>', esc_url( $url ), get_the_title( $course_id ) );
225: }
226: if ( isset( $_GET['lesson_id'] ) ) {
227: $lesson_id = intval( $_GET['lesson_id'] );
228: $title .= ' <span class="lesson-title">> ' . get_the_title( intval( $lesson_id ) ) . '</span>';
229: }
230: ?>
231: <h1><?php echo apply_filters( 'sensei_learners_nav_title', $title ); ?></h1>
232: <?php
233: }
234:
235: public function get_redirect_url() {
236:
237:
238: $data = $_POST['data'];
239: $course_data = array();
240: parse_str( $data, $course_data );
241:
242: $course_cat = intval( $course_data['course_cat'] );
243:
244: $redirect_url = apply_filters( 'sensei_ajax_redirect_url', add_query_arg( array( 'page' => $this->page_slug, 'course_cat' => $course_cat ), admin_url( 'admin.php' ) ) );
245:
246: echo esc_url_raw( $redirect_url );
247: die();
248: }
249:
250: public function remove_user_from_post() {
251:
252:
253: $data = sanitize_text_field( $_POST['data'] );
254: $action_data = array();
255: parse_str( $data, $action_data );
256:
257:
258:
259:
260:
261:
262: $nonce = '';
263: if ( isset($_POST['remove_user_from_post_nonce']) ) {
264: $nonce = esc_html( $_POST['remove_user_from_post_nonce'] );
265: }
266: $post = get_post( intval( $action_data[ 'post_id' ] ) );
267:
268:
269: $may_remove_user = false;
270: if( current_user_can('manage_sensei')
271: || $post->post_author == get_current_user_id() ){
272:
273: $may_remove_user = true;
274:
275: }
276:
277: if( ! wp_verify_nonce( $nonce, 'remove_user_from_post_nonce' )
278: || ! is_a( $post ,'WP_Post' )
279: || ! $may_remove_user ){
280:
281: die('');
282:
283: }
284:
285: if( $action_data['user_id'] && $action_data['post_id'] && $action_data['post_type'] ) {
286:
287: $user_id = intval( $action_data['user_id'] );
288: $post_id = intval( $action_data['post_id'] );
289: $post_type = sanitize_text_field( $action_data['post_type'] );
290:
291: $user = get_userdata( $user_id );
292:
293: switch( $post_type ) {
294:
295: case 'course':
296:
297: $removed = Sensei_Utils::sensei_remove_user_from_course( $post_id, $user_id );
298:
299: break;
300:
301: case 'lesson':
302:
303: $removed = Sensei_Utils::sensei_remove_user_from_lesson( $post_id, $user_id );
304:
305: break;
306:
307: }
308:
309: if( $removed ) {
310: die( 'removed' );
311: }
312:
313: }
314:
315: die('');
316: }
317:
318: public function json_search_users() {
319:
320:
321: check_ajax_referer( 'search-users', 'security' );
322:
323: $term = sanitize_text_field( stripslashes( $_GET['term'] ) );
324:
325: if ( empty( $term ) ) {
326: die();
327: }
328:
329: $default = isset( $_GET['default'] ) ? $_GET['default'] : __( 'None', 'woocommerce' );
330:
331: $found_users = array( '' => $default );
332:
333: $users_query = new WP_User_Query( apply_filters( 'sensei_json_search_users_query', array(
334: 'fields' => 'all',
335: 'orderby' => 'display_name',
336: 'search' => '*' . $term . '*',
337: 'search_columns' => array( 'ID', 'user_login', 'user_email', 'user_nicename','user_firstname','user_lastname' )
338: ), $term ) );
339:
340: $users = $users_query->get_results();
341:
342: if ( $users ) {
343: foreach ( $users as $user ) {
344: $full_name = Sensei_Learner::get_full_name( $user->ID );
345:
346: if( trim($user->display_name ) == trim( $full_name ) ){
347:
348: $name = $full_name;
349:
350: }else{
351:
352: $name = $full_name . ' ['. $user->display_name .']';
353:
354: }
355:
356: $found_users[ $user->ID ] = $name . ' (#' . $user->ID . ' – ' . sanitize_email( $user->user_email ) . ')';
357: }
358: }
359:
360: wp_send_json( $found_users );
361: }
362:
363: public function add_new_learners() {
364:
365: $result = false;
366:
367: if( ! isset( $_POST['add_learner_submit'] ) ) return $result;
368:
369: if ( ! isset( $_POST['add_learner_nonce'] ) || ! wp_verify_nonce( $_POST['add_learner_nonce'], 'add_learner_to_sensei' ) ) return $result;
370:
371: if( ( ! isset( $_POST['add_user_id'] ) || '' == $_POST['add_user_id'] ) || ! isset( $_POST['add_post_type'] ) || ! isset( $_POST['add_course_id'] ) || ! isset( $_POST['add_lesson_id'] ) ) return $result;
372:
373: $post_type = $_POST['add_post_type'];
374: $user_id = absint( $_POST['add_user_id'] );
375: $course_id = absint( $_POST['add_course_id'] );
376: $lesson_id = isset( $_POST['add_lesson_id'] ) ? $_POST['add_lesson_id'] : '';
377:
378: switch( $post_type ) {
379: case 'course':
380:
381: $result = Sensei_Utils::user_start_course( $user_id, $course_id );
382:
383:
384: if( isset( $_POST['add_complete_course'] ) && 'yes' == $_POST['add_complete_course'] ) {
385:
386: $lesson_ids = Sensei()->course->course_lessons( $course_id, 'any', 'ids' );
387:
388: foreach( $lesson_ids as $id ) {
389: Sensei_Utils::sensei_start_lesson( $id, $user_id, true );
390: }
391:
392:
393: Sensei_Utils::user_complete_course( $course_id, $user_id );
394:
395: do_action( 'sensei_user_course_end', $user_id, $course_id );
396: }
397:
398: break;
399:
400: case 'lesson':
401:
402: $complete = false;
403: if( isset( $_POST['add_complete_lesson'] ) && 'yes' == $_POST['add_complete_lesson'] ) {
404: $complete = true;
405: }
406:
407: $result = Sensei_Utils::sensei_start_lesson( $lesson_id, $user_id, $complete );
408:
409:
410: Sensei_Utils::user_complete_course( $course_id, $user_id );
411:
412: break;
413: }
414:
415:
416: $query_args = array( 'page' => $this->page_slug, 'view' => 'learners' );
417:
418: if( $result ) {
419:
420: if( $course_id ) {
421: $query_args['course_id'] = $course_id;
422: }
423:
424: if( $lesson_id ) {
425: $query_args['lesson_id'] = $lesson_id;
426: }
427:
428: $query_args['message'] = 'success';
429:
430: } else {
431: $query_args['message'] = 'error';
432: }
433:
434: $redirect_url = apply_filters( 'sensei_learners_add_learner_redirect_url', add_query_arg( $query_args, admin_url( 'admin.php' ) ) );
435:
436: wp_safe_redirect( esc_url_raw( $redirect_url ) );
437: exit;
438: }
439:
440: public function add_learner_notices() {
441: if( isset( $_GET['page'] ) && $this->page_slug == $_GET['page'] && isset( $_GET['message'] ) && $_GET['message'] ) {
442: if( 'success' == $_GET['message'] ) {
443: $msg = array(
444: 'updated',
445: __( 'Learner added successfully!', 'woothemes-sensei' ),
446: );
447: } else {
448: $msg = array(
449: 'error',
450: __( 'Error adding learner.', 'woothemes-sensei' ),
451: );
452: }
453: ?>
454: <div class="learners-notice <?php echo $msg[0]; ?>">
455: <p><?php echo $msg[1]; ?></p>
456: </div>
457: <?php
458: }
459: }
460:
461: 462: 463: 464: 465: 466: 467: 468: 469: 470: 471: 472:
473: public function get_learner_full_name( $user_id ){
474:
475: return Sensei_Learner::get_full_name( $user_id );
476:
477: }
478:
479: }
480:
481: 482: 483: 484: 485:
486: class WooThemes_Sensei_Learners extends Sensei_Learner_Management{}
487: