PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7.3
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7.3
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 / admin / lp-admin-functions.php

lp-admin-functions.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7.3, at inc/admin/lp-admin-functions.php

2,549 lines 64.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Common functions used for admin
4 *
5 * @package LearnPress
6 * @author ThimPress
7 * @version 1.0
8 */
9
10 /**
11 * Prevent loading this file directly
12 */
13 defined( 'ABSPATH' ) || exit();
14
15 if ( ! function_exists( 'learn_press_add_row_action_link' ) ) {
16 /**
17 * Setup action links to the admin course, lesson, quiz, question. e.g: Add Duplicate link, hide View link for lesson, quiz so on.
18 *
19 * @param $actions
20 *
21 * @return mixed
22 */
23 function learn_press_add_row_action_link( $actions ) {
24
25 global $post;
26
27 if ( LP_COURSE_CPT == $post->post_type ) {
28 $duplicate_link = '#';
29 $duplicate_link = array(
30 array(
31 'link' => $duplicate_link,
32 'title' => _x( 'Duplicate', 'copy course', 'learnpress' ),
33 'class' => 'lp-duplicate-post lp-duplicate-course',
34 'data' => $post->ID,
35 ),
36 );
37
38 $links = apply_filters( 'learn_press_row_action_links', $duplicate_link );
39
40 if ( count( $links ) > 1 ) {
41 $drop_down = array( '<ul class="lpr-row-action-dropdown">' );
42
43 foreach ( $links as $link ) {
44 $drop_down[] = '<li>' . sprintf(
45 '<a href="%s" class="%s" data-post-id="%s">%s</a>',
46 $link['link'],
47 $link['class'],
48 $link['data'],
49 $link['title']
50 ) . '</li>';
51 };
52
53 $drop_down[] = '</ul>';
54 $link = sprintf(
55 '<div class="lpr-row-actions"><a href="%s">%s</a>%s</div>',
56 'javascript: void(0);',
57 __( 'Course', 'learnpress' ),
58 join( "\n", $drop_down )
59 );
60
61 } else {
62 $link = array_shift( $links );
63 $link = sprintf(
64 '<a href="%s" class="%s" data-post-id="%s">%s</a>',
65 $link['link'],
66 $link['class'],
67 $link['data'],
68 $link['title']
69 );
70 }
71
72 $actions['lp-duplicate-row-action'] = $link;
73
74 } elseif ( LP_QUIZ_CPT === $post->post_type ) {
75 unset( $actions['view'] );
76 $link = sprintf(
77 '<a href="#" class="lp-duplicate-post lp-duplicate-quiz" data-post-id="%s">%s</a>',
78 $post->ID,
79 _x( 'Duplicate', 'copy quiz', 'learnpress' )
80 );
81 $actions['lp-duplicate-row-action'] = $link;
82
83 } elseif ( LP_QUESTION_CPT === $post->post_type ) {
84 unset( $actions['view'] );
85 $link = sprintf(
86 '<a href="#" class="lp-duplicate-post lp-duplicate-question" data-post-id="%s">%s</a>',
87 $post->ID,
88 _x( 'Duplicate', 'copy question', 'learnpress' )
89 );
90 $actions['lp-duplicate-row-action'] = $link;
91
92 } elseif ( LP_LESSON_CPT === $post->post_type ) {
93 unset( $actions['view'] );
94 $link = sprintf(
95 '<a href="#" class="lp-duplicate-post lp-duplicate-lesson" data-post-id="%s">%s</a>',
96 $post->ID,
97 _x( 'Duplicate', 'copy lesson', 'learnpress' )
98 );
99 $actions['lp-duplicate-row-action'] = $link;
100 }
101
102 return apply_filters( 'learn-press/row-action-links', $actions );
103 }
104
105 add_filter( 'post_row_actions', 'learn_press_add_row_action_link' );
106 add_filter( 'page_row_actions', 'learn_press_add_row_action_link' );
107 }
108
109 function learn_press_is_hidden_post_box( $id, $user_id = 0 ) {
110 if ( ! $user_id ) {
111 $user_id = get_current_user_id();
112 }
113
114 $data = learn_press_get_user_option( 'post-closed-box' );
115 if ( ! $data ) {
116 $data = array();
117 }
118
119 return false !== array_search( $id, $data );
120 }
121
122 /**
123 * Get html view path for admin to display
124 *
125 * @param $name
126 * @param $plugin_file
127 *
128 * @return mixed
129 */
130 function learn_press_get_admin_view( $name, $plugin_file = null ) {
131 if ( ! preg_match( '/\.(html|php)$/', $name ) ) {
132 $name .= '.php';
133 }
134 if ( $plugin_file ) {
135 $view = dirname( $plugin_file ) . '/inc/admin/views/' . $name;
136 } else {
137 $view = LearnPress::instance()->plugin_path( 'inc/admin/views/' . $name );
138 }
139
140 return apply_filters( 'learn_press_admin_view', $view, $name );
141 }
142
143 function learn_press_admin_view_content( $name, $args = array() ) {
144 return learn_press_admin_view( $name, $args, false, true );
145 }
146
147 /**
148 * Find a full path of a view and display the content in admin
149 *
150 * @param $name
151 * @param array $args
152 * @param bool|false $include_once
153 * @param bool
154 *
155 * @return bool
156 */
157 function learn_press_admin_view( $name, $args = array(), $include_once = false, $return = false ) {
158 $view = learn_press_get_admin_view( $name, ! empty( $args['plugin_file'] ) ? $args['plugin_file'] : null );
159
160 if ( file_exists( $view ) ) {
161
162 ob_start();
163
164 is_array( $args ) && extract( $args );
165
166 do_action( 'learn_press_before_display_admin_view', $name, $args );
167
168 if ( $include_once ) {
169 include_once $view;
170 } else {
171 include $view;
172 }
173
174 do_action( 'learn_press_after_display_admin_view', $name, $args );
175 $output = ob_get_clean();
176
177 if ( ! $return ) {
178 learn_press_echo_vuejs_write_on_php( $output );
179 }
180
181 return $return ? $output : true;
182 }
183
184 return false;
185 }
186
187 /**
188 * List all pages as a dropdown with "Add New Page" option
189 *
190 * @param $name
191 * @param bool|false $selected
192 * @param array $args
193 *
194 * @return mixed|string
195 */
196 function learn_press_pages_dropdown( $name, $selected = false, $args = array() ) {
197 $id = null;
198 $class = null;
199 $css = null;
200 $before = array(
201 'add_new_page' => __( '[ Add a new page ]', 'learnpress' ),
202 );
203 $after = null;
204 $echo = true;
205 $allow_create = true;
206
207 if ( func_num_args() == 1 && is_array( $name ) ) {
208 $args = $name;
209 }
210
211 is_array( $args ) && extract( $args );
212
213 if ( empty( $id ) ) {
214 $id = $name;
215 }
216
217 $class .= 'list-pages lp-list-pages learn-press-select2';
218
219 $args = array(
220 'name' => $name,
221 'id' => $id,
222 'sort_column' => 'menu_order',
223 'sort_order' => 'ASC',
224 'show_option_none' => __( 'Select Page', 'learnpress' ),
225 'class' => $class,
226 'echo' => false,
227 'selected' => $selected,
228 'allow_create' => true,
229 );
230 $output = wp_dropdown_pages( $args );
231 $replace = '';
232
233 if ( $class ) {
234 $replace .= ' class="' . $class . '"';
235 }
236
237 if ( $css ) {
238 $replace .= ' style="' . $css . '"';
239 }
240
241 $replace .= ' data-selected="' . $selected . '"';
242 $replace .= " data-placeholder='" . __( 'Select a page&hellip;', 'learnpress' ) . "' id=";
243 $output = '<div class="list-pages-wrapper">' . str_replace( ' id=', $replace, $output );
244
245 if ( $before ) {
246 $before_output = array();
247
248 foreach ( $before as $v => $l ) {
249 $before_output[] = sprintf( '<option value="%s">%s</option>', $v, $l );
250 }
251
252 $before_output = join( "\n", $before_output );
253 $output = preg_replace(
254 '!(<option class=".*" value="[0-9]+".*>.*</option>)!',
255 $before_output . "\n$1",
256 $output,
257 1
258 );
259 }
260
261 $output = str_replace( '<option class="level-0" value="00000">#0 (no title)</option>', '', $output );
262
263 if ( $selected && get_post_status( $selected ) !== 'publish' ) {
264 $selected = 0;
265 }
266
267 if ( $allow_create ) {
268 ob_start(); ?>
269
270 <?php echo esc_html( _x( 'or', 'dropdown pages', 'learnpress' ) ); ?>
271
272 <button class="button button-quick-add-page" data-id="<?php echo esc_attr( $id ); ?>" type="button">
273 <?php esc_html_e( 'Create new', 'learnpress' ); ?>
274 </button>
275 <?php echo '</div>'; ?>
276
277 <p class="quick-add-page-inline <?php echo esc_attr( $id ); ?> hide-if-js">
278 <input type="text" placeholder="<?php esc_attr_e( 'New page title', 'learnpress' ); ?>"/>
279 <button class="button" type="button">
280 <?php esc_html_e( 'Ok [Enter]', 'learnpress' ); ?>
281 </button>
282 <a href=""><?php esc_html_e( 'Cancel [ESC]', 'learnpress' ); ?></a>
283 </p>
284
285 <p class="quick-add-page-actions <?php echo esc_attr( $id ); ?><?php echo esc_attr( $selected ? '' : ' hide-if-js' ); ?>">
286 <a class="edit-page" href="<?php echo get_edit_post_link( $selected ); ?>"
287 target="_blank"><?php esc_html_e( 'Edit page', 'learnpress' ); ?></a>
288 &#124;
289 <a class="view-page" href="<?php echo get_permalink( $selected ); ?>"
290 target="_blank"><?php esc_html_e( 'View page', 'learnpress' ); ?></a>
291 </p>
292
293 <?php
294 $output .= ob_get_clean();
295 } else {
296 $output .= '</div>';
297 }
298
299 $output = sprintf( '<div class="learn-press-dropdown-pages">%s</div>', $output );
300
301 if ( $echo ) {
302 $allowed_html = wp_kses_allowed_html( 'post' );
303 $allowed_html['select'] = [
304 'name' => [],
305 ];
306 $allowed_html['option'] = [
307 'value' => [],
308 'selected' => [],
309 'class' => [],
310 ];
311 $allowed_html['input'] = [
312 'type' => [],
313 'placeholder' => [],
314 ];
315
316 echo wp_kses( $output, $allowed_html );
317 }
318
319 return $output;
320 }
321
322 /**
323 * List all registered question types into dropdown
324 *
325 * @param array
326 *
327 * @return string
328 */
329 function learn_press_dropdown_question_types( $args = array() ) {
330 $args = wp_parse_args(
331 $args,
332 array(
333 'name' => 'learn-press-dropdown-question-types',
334 'id' => '',
335 'class' => '',
336 'selected' => '',
337 'echo' => true,
338 )
339 );
340
341 if ( ! $args['id'] ) {
342 $args['id'] = $args['name'];
343 }
344
345 $args['class'] = 'lp-dropdown-question-types' . ( $args['class'] ? ' ' . $args['class'] : '' );
346 $types = learn_press_question_types();
347 $output = sprintf(
348 '<select name="%s" id="%s" class="%s"%s>',
349 $args['name'],
350 $args['id'],
351 $args['class'],
352 $args['selected'] ? 'data-selected="' . $args['selected'] . '"' : ''
353 );
354
355 foreach ( $types as $slug => $name ) {
356 $output .= sprintf(
357 '<option value="%s"%s>%s</option>',
358 $slug,
359 selected( $slug == $args['selected'], true, false ),
360 $name
361 );
362 }
363
364 $output .= '</select>';
365
366 if ( $args['echo'] ) {
367 echo wp_kses_post( $output );
368 }
369
370 return $output;
371 }
372
373 /**
374 * List all registered question types into dropdown
375 *
376 * @param array $args
377 * @param LP_Question $question
378 *
379 * @return string
380 */
381 function learn_press_field_question_duration( $args = array(), $question = null ) {
382 global $post;
383
384 $duration_type = get_post_meta( $post->ID, '_lp_duration_type', true );
385 $value = get_post_meta( $question->id, '_question_duration', true );
386
387 $wrap_class = 'learn-press-question-duration';
388
389 if ( 'questions_duration' !== $duration_type ) {
390 $wrap_class .= ' hide';
391 }
392
393 $args = wp_parse_args(
394 $args,
395 array(
396 'name' => 'learn_press_question[' . $question->id . '][duration]',
397 'id' => 'learn-press-question-duration-' . $question->id,
398 'class' => 'learn-press-question-duration',
399 'selected' => '',
400 'echo' => true,
401 'value' => 0,
402 'step' => 1,
403 'min' => 0,
404 'placeholder' => __( 'Minutes', 'learnpress' ),
405 )
406 );
407
408 $args['value'] = $value;
409
410 if ( ! $args['id'] ) {
411 $args['id'] = $args['name'];
412 }
413
414 return '<span class="' . esc_attr( $wrap_class ) . '">' . sprintf(
415 '<input type="number" class="%s" name="%s" id="%s" value="%s" step="%s" min="%s" max="%s" placeholder="%s"/>',
416 $args['class'],
417 $args['name'],
418 empty( $args['clone'] ) ? $args['id'] : '',
419 $args['value'],
420 $args['step'],
421 $args['min'],
422 ! empty( $args['max'] ) ? $args['max'] : '',
423 $args['placeholder']
424 ) . $args['placeholder'] . '</span>';
425 }
426
427 /**
428 * Displays email formats support into a dropdown
429 *
430 * @param array $args
431 *
432 * @return string
433 */
434 function learn_press_email_formats_dropdown( $args = array() ) {
435 $args = wp_parse_args(
436 $args,
437 array(
438 'name' => 'learn-press-dropdown-email-formats',
439 'id' => '',
440 'class' => '',
441 'selected' => '',
442 'option_none' => '',
443 'echo' => true,
444 )
445 );
446
447 $formats = array(
448 'plain_text' => __( 'Plain Text', 'learnpress' ),
449 'html' => __( 'HTML', 'learnpress' ),
450 );
451
452 if ( empty( $args['id'] ) ) {
453 $args['id'] = sanitize_file_name( $args['name'] );
454 }
455
456 $output = sprintf( '<select name="%s" id="%s" class="%s" %s>', $args['name'], $args['id'], $args['class'], '' );
457
458 if ( $args['option_none'] ) {
459 if ( is_array( $args['option_none'] ) ) {
460 $text = reset( $args['option_none'] );
461 $value = key( $args['option_none'] );
462 } else {
463 $text = $args['option_none'];
464 $value = '';
465 }
466
467 $output .= sprintf( '<option value="%s">%s</option>', $value, $text );
468 }
469
470 foreach ( $formats as $name => $text ) {
471 $output .= sprintf(
472 '<option value="%s" %s>%s</option>',
473 $name,
474 selected( $args['selected'] == $name, true, false ),
475 $text
476 ) . "\n";
477 }
478 $output .= '</select>';
479
480 if ( $args['echo'] ) {
481 echo wp_kses_post( $output );
482 }
483
484 return $output;
485 }
486
487 /**
488 * Return array of email formats.
489 *
490 * @return mixed
491 */
492 function learn_press_email_formats() {
493 $formats = array(
494 'plain' => esc_html__( 'Plain Text', 'learnpress' ),
495 'html' => esc_html__( 'HTML', 'learnpress' ),
496 );
497
498 return apply_filters( 'learn-press/email-formats', $formats );
499 }
500
501 function learn_press_trim_content( $content, $count = 0 ) {
502 $content = preg_replace( '/(?<=\S,)(?=\S)/', ' ', $content );
503 $content = str_replace( "\n", ' ', $content );
504 $content = explode( ' ', $content );
505
506 $count = $count > 0 ? $count : sizeof( $content ) - 1;
507 $full = $count >= sizeof( $content ) - 1;
508
509 $content = array_slice( $content, 0, $count );
510 $content = implode( ' ', $content );
511
512 if ( ! $full ) {
513 $content .= '...';
514 }
515
516 return $content;
517 }
518
519 /**
520 * Get list of themes that support LearnPress.
521 *
522 * @return mixed
523 */
524 function learn_press_get_education_themes() {
525
526 // New theme can be added here
527 return apply_filters(
528 'learn-press/education-themes',
529 array(
530 '23451388' => 'kindergarten',
531 '22773871' => 'ivy-school',
532 '20370918' => 'wordpress-lms',
533 '14058034' => 'eduma',
534 '17097658' => 'coach',
535 '11797847' => 'lms',
536 )
537 );
538 }
539
540 if ( ! function_exists( 'learn_press_get_item_referral' ) ) {
541 /**
542 * Set item link referral.
543 *
544 * @param int|string $item_id
545 *
546 * @return string
547 */
548 function learn_press_get_item_referral( $item_id ) {
549 $affiliate_links = array(
550 14058034 => 'https://1.envato.market/G5Ook', // Eduma
551 22773871 => 'https://1.envato.market/akrzZ', // Ivy-school
552 20370918 => 'https://1.envato.market/13Zkd', // Course Builder LMS
553 17097658 => 'https://1.envato.market/Xq2Ra', // Coach
554 23451388 => 'https://1.envato.market/oWov9', // StarKid
555 11797847 => 'https://1.envato.market/zknvM', // Epsilon
556 13321455 => 'https://1.envato.market/G5Rkk', // Sailing
557 19029758 => 'https://1.envato.market/mAYdZ', // Travel Tour Booking
558 12124219 => 'https://1.envato.market/qJYdO', // Resca
559 18828322 => 'https://1.envato.market/VW2K3', // LuxStay
560 8254575 => 'https://1.envato.market/xWYdO', // Squareroot
561 13782850 => 'https://1.envato.market/Qo71z',
562 14025178 => 'https://1.envato.market/9R0oQ',
563 17739078 => 'https://1.envato.market/jkYda',
564 16210005 => 'https://1.envato.market/56oJD',
565 11733602 => 'https://1.envato.market/keYdv',
566 13513609 => 'https://1.envato.market/aq7dQ',
567 19693761 => 'https://1.envato.market/A976D',
568 12532973 => 'https://1.envato.market/Ge79B',
569 19305239 => 'https://1.envato.market/10JAB',
570 23716060 => 'https://1.envato.market/ZO7WW',
571 20466233 => 'https://1.envato.market/gjYd0',
572 21070438 => 'https://1.envato.market/xPz65',
573 20794183 => 'https://1.envato.market/o1YdY',
574 20979215 => 'https://1.envato.market/03R5V',
575 11151269 => 'https://1.envato.market/Br7L4',
576 8905392 => 'https://1.envato.market/zEYd7',
577 23168294 => 'https://1.envato.market/Wn7on',
578 17719422 => 'https://1.envato.market/0WVaL',
579 21680592 => 'https://1.envato.market/qqO6y',
580 );
581
582 return isset( $affiliate_links[ $item_id ] ) ? $affiliate_links[ $item_id ] : 'https://themeforest.net/user/thimpress/portfolio/';
583 }
584 }
585
586 /**
587 * Display advertisement about related themes at the bottom of admin pages.
588 *
589 * @updated 12 Nov 2018 - Enable/Disable shuffle the list of themes
590 *
591 * @return bool|void
592 */
593 function learn_press_footer_advertisement() {
594 $admin_post_type = array(
595 'lp_course',
596 'lp_lesson',
597 'lp_quiz',
598 'lp_question',
599 'lp_order',
600 );
601
602 // And our admin pages
603 $pages = array(
604 'learnpress_page_learn-press-statistics',
605 'learnpress_page_learn-press-settings',
606 'learnpress_page_learn-press-tools',
607
608 );
609
610 $screen = get_current_screen();
611
612 if ( ! $screen ) {
613 return;
614 }
615
616 if ( ! ( ( in_array(
617 $screen->post_type,
618 $admin_post_type
619 ) && $screen->base === 'edit' ) || ( in_array( $screen->id, $pages ) ) ) ) {
620 return;
621 }
622
623 $theme_ids = learn_press_get_education_themes();
624 $current_theme = wp_get_theme();
625
626 $include = array_keys( $theme_ids );
627
628 $key = array_search( $current_theme->name, $theme_ids, true );
629
630 if ( false !== $key ) {
631 unset( $theme_ids[ $key ] );
632 }
633
634 $list_themes = (array) LP_Plugins_Helper::get_related_themes(
635 'education',
636 array(
637 'include' => $include,
638 )
639 );
640
641 if ( empty( $list_themes ) ) {
642 return;
643 }
644
645 // Disable shuffle themes for 3 days
646 $shuffle = LP_Settings::instance()->get( 'ad_shuffle_themes' );
647
648 if ( ! $shuffle ) {
649 if ( wp_next_scheduled( 'learn-press/schedule-enable-shuffle-themes' ) === false ) {
650 wp_schedule_single_event( time() + 3 * DAY_IN_SECONDS, 'learn-press/schedule-enable-shuffle-themes' );
651 }
652
653 // Keep the first theme always in #1 and shuffle other themes
654 $first_theme = array_shift( $list_themes );
655 shuffle( $list_themes );
656 array_unshift( $list_themes, $first_theme );
657 } else {
658 shuffle( $list_themes );
659 }
660 ?>
661
662 <div id="learn-press-advertisement" class="learn-press-advertisement-slider">
663 <?php
664 foreach ( $list_themes as $theme ) {
665 if ( empty( $theme['url'] ) ) {
666 continue;
667 }
668
669 $url = learn_press_get_item_referral( $theme['id'] );
670 $full_description = learn_press_trim_content( $theme['description'] );
671 $short_description = learn_press_trim_content( $theme['description'], 75 );
672 $url_demo = $theme['attributes'][4]['value'];
673 ?>
674
675 <div id="thimpress-<?php echo esc_attr( $theme['id'] ); ?>" class="slide-item">
676 <div class="slide-thumbnail">
677 <a href="<?php echo esc_url_raw( $url ); ?>">
678 <img src="<?php echo esc_url_raw( $theme['previews']['landscape_preview']['landscape_url'] ); ?>"/>
679 </a>
680 </div>
681
682 <div class="slide-detail">
683 <h2><a href="<?php echo esc_url_raw( $url ); ?>"><?php echo esc_html( $theme['name'] ); ?></a></h2>
684 <p class="slide-description description-full">
685 <?php echo wp_kses_post( $full_description ); ?>
686 </p>
687
688 <p class="slide-description description-short">
689 <?php echo wp_kses_post( $short_description ); ?>
690 </p>
691
692 <p class="slide-controls">
693 <a href="<?php echo esc_url_raw( $url ); ?>" class="button button-primary"
694 target="_blank"><?php esc_html_e( 'Get it now', 'learnpress' ); ?></a>
695 <a href="<?php echo esc_url_raw( $url_demo ); ?>" class="button"
696 target="_blank"><?php esc_html_e( 'View Demo', 'learnpress' ); ?></a>
697 </p>
698 </div>
699 </div>
700
701 <?php } ?>
702 </div>
703 <?php
704 }
705
706 /**
707 * Count number of orders between to dates
708 *
709 * @param string
710 * @param int
711 *
712 * @return int
713 */
714 function learn_press_get_order_by_time( $by, $time ) {
715 global $wpdb;
716
717 $user_id = get_current_user_id();
718
719 $y = gmdate( 'Y', $time );
720 $m = gmdate( 'm', $time );
721 $d = gmdate( 'd', $time );
722
723 switch ( $by ) {
724 case 'days':
725 $orders = $wpdb->get_var(
726 $wpdb->prepare(
727 "SELECT COUNT(*)
728 FROM $wpdb->posts AS p
729 INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
730 WHERE p.post_author = %d
731 AND p.post_type = %s
732 AND p.post_status = %s
733 AND m.meta_key = %s
734 AND m.meta_value = %s
735 AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s AND DAY(p.post_date) = %s",
736 $user_id,
737 LP_ORDER_CPT,
738 'publish',
739 '_learn_press_transaction_status',
740 'completed',
741 $y,
742 $m,
743 $d
744 )
745 );
746 break;
747 case 'months':
748 $orders = $wpdb->get_var(
749 $wpdb->prepare(
750 "SELECT COUNT(*)
751 FROM $wpdb->posts AS p
752 INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
753 WHERE p.post_author = %d
754 AND p.post_type = %s
755 AND p.post_status = %s
756 AND m.meta_key = %s
757 AND m.meta_value = %s
758 AND YEAR(p.post_date) = %s AND MONTH(p.post_date) = %s",
759 $user_id,
760 LP_ORDER_CPT,
761 'publish',
762 '_learn_press_transaction_status',
763 'completed',
764 $y,
765 $m
766 )
767 );
768 break;
769 }
770
771 return $orders;
772 }
773
774 /**
775 * Count number of orders by status
776 *
777 * @param string Status of the orders
778 *
779 * @return int
780 */
781 function learn_press_get_courses_by_status( $status ) {
782 global $wpdb;
783
784 $user_id = get_current_user_id();
785
786 $courses = $wpdb->get_var(
787 $wpdb->prepare(
788 "SELECT COUNT(*)
789 FROM $wpdb->posts
790 WHERE post_author = %d
791 AND post_type = %s
792 AND post_status = %s",
793 $user_id,
794 LP_COURSE_CPT,
795 $status
796 )
797 );
798
799 return $courses;
800 }
801
802 /**
803 * Count number of orders by price
804 *
805 * @param string
806 *
807 * @return int
808 */
809 function learn_press_get_courses_by_price( $fee ) {
810 global $wpdb;
811
812 $user_id = get_current_user_id();
813
814 $courses = $wpdb->get_var(
815 $wpdb->prepare(
816 "SELECT COUNT(*)
817 FROM $wpdb->posts AS p
818 INNER JOIN $wpdb->postmeta AS m ON p.ID = m.post_id
819 WHERE p.post_author = %d
820 AND p.post_type = %s
821 AND p.post_status IN (%s, %s)
822 AND m.meta_key = %s
823 AND m.meta_value = %s",
824 $user_id,
825 LP_COURSE_CPT,
826 'publish',
827 'pending',
828 '_lpr_course_payment',
829 $fee
830 )
831 );
832
833 return $courses;
834 }
835
836 /**
837 * Get data about students to render in chart
838 *
839 * @param null $from
840 * @param null $by
841 * @param float $time_ago
842 *
843 * @return array
844 */
845 function learn_press_get_chart_students( $from = null, $by = null, $time_ago = 0 ) {
846 $labels = array();
847 $datasets = array();
848
849 if ( is_null( $from ) ) {
850 $from = current_time( 'mysql', 1 );
851 }
852
853 if ( is_null( $by ) ) {
854 $by = 'days';
855 }
856
857 switch ( $by ) {
858 case 'days':
859 $date_format = 'M d';
860 break;
861 case 'months':
862 $date_format = 'M Y';
863 break;
864 case 'years':
865 $date_format = 'Y';
866 break;
867 }
868
869 for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
870 $labels[] = gmdate( $date_format, strtotime( "$i $by", strtotime( $from ) ) );
871 $datasets[0]['data'][] = learn_press_get_order_by_time( $by, strtotime( "$i $by", strtotime( $from ) ) );
872 }
873
874 $colors = learn_press_get_admin_colors();
875 $datasets[0]['fillColor'] = 'rgba(255,255,255,0.1)';
876 $datasets[0]['strokeColor'] = $colors[0];
877 $datasets[0]['pointColor'] = $colors[0];
878 $datasets[0]['pointStrokeColor'] = $colors[2];
879 $datasets[0]['pointHighlightFill'] = $colors[2];
880 $datasets[0]['pointHighlightStroke'] = $colors[0];
881
882 return array(
883 'labels' => $labels,
884 'datasets' => $datasets,
885 );
886 }
887
888 /**
889 * Get data about students to render in chart
890 *
891 * @param null $from
892 * @param null $by
893 * @param float $time_ago
894 *
895 * @return array
896 */
897 function learn_press_get_chart_users( $from = null, $by = null, $time_ago = 0 ) {
898 global $wpdb;
899
900 $labels = array();
901 $datasets = array();
902
903 if ( is_null( $from ) ) {
904 $from = current_time( 'mysql', 1 );
905 }
906
907 if ( is_null( $by ) ) {
908 $by = 'days';
909 }
910
911 $results = array(
912 'all' => array(),
913 'instructors' => array(),
914 );
915
916 $from_time = is_numeric( $from ) ? $from : strtotime( $from );
917
918 switch ( $by ) {
919 case 'days':
920 $date_format = 'M d Y';
921 $_from = - $time_ago + 1;
922 $_from = gmdate( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
923 $_to = date( 'Y-m-d', $from_time );
924 $_sql_format = '%Y-%m-%d';
925 $_key_format = 'Y-m-d';
926 break;
927 case 'months':
928 $date_format = 'M Y';
929 $_from = - $time_ago + 1;
930 $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
931 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
932 $_to = date( 'Y-m-' . $days, $from_time );
933 $_sql_format = '%Y-%m';
934 $_key_format = 'Y-m';
935 break;
936 case 'years':
937 $date_format = 'Y';
938 $_from = - $time_ago + 1;
939 $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
940 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
941 $_to = date( 'Y-12-' . $days, $from_time );
942 $_sql_format = '%Y';
943 $_key_format = 'Y';
944
945 break;
946 }
947 $query = $wpdb->prepare(
948 "
949 SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
950 FROM {$wpdb->users} u
951 WHERE 1
952 GROUP BY d
953 HAVING d BETWEEN %s AND %s
954 ORDER BY d ASC
955 ",
956 $_sql_format,
957 $_from,
958 $_to
959 );
960
961 if ( $_results = $wpdb->get_results( $query ) ) {
962 foreach ( $_results as $k => $v ) {
963 $results['all'][ $v->d ] = $v;
964 }
965 }
966
967 $query = $wpdb->prepare(
968 "
969 SELECT count(u.ID) as c, DATE_FORMAT( u.user_registered, %s) as d
970 FROM {$wpdb->users} u
971 INNER JOIN {$wpdb->usermeta} um ON um.user_id = u.ID AND um.meta_key = %s AND ( um.meta_value LIKE %s OR um.meta_value LIKE %s )
972 WHERE 1
973 GROUP BY d
974 HAVING d BETWEEN %s AND %s
975 ORDER BY d ASC
976 ",
977 $_sql_format,
978 'wp_capabilities',
979 '%' . $wpdb->esc_like( 's:13:"administrator"' ) . '%',
980 '%' . $wpdb->esc_like( 's:10:"lp_teacher"' ) . '%',
981 $_from,
982 $_to
983 );
984
985 if ( $_results = $wpdb->get_results( $query ) ) {
986 foreach ( $_results as $k => $v ) {
987 $results['instructors'][ $v->d ] = $v;
988 }
989 }
990
991 for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
992 $date = strtotime( "$i $by", $from_time );
993 $labels[] = date( $date_format, $date );
994 $key = date( $_key_format, $date );
995
996 $all = ! empty( $results['all'][ $key ] ) ? $results['all'][ $key ]->c : 0;
997 $instructors = ! empty( $results['instructors'][ $key ] ) ? $results['instructors'][ $key ]->c : 0;
998
999 $datasets[0]['data'][] = $all;
1000 $datasets[1]['data'][] = $instructors;
1001 $datasets[2]['data'][] = $all - $instructors;
1002 }
1003
1004 $dataset_params = array(
1005 array(
1006 'color1' => 'rgba(47, 167, 255, %s)',
1007 'color2' => '#FFF',
1008 'label' => __( 'All', 'learnpress' ),
1009 ),
1010 array(
1011 'color1' => 'rgba(212, 208, 203, %s)',
1012 'color2' => '#FFF',
1013 'label' => __( 'Instructors', 'learnpress' ),
1014 ),
1015 array(
1016 'color1' => 'rgba(234, 199, 155, %s)',
1017 'color2' => '#FFF',
1018 'label' => __( 'Students', 'learnpress' ),
1019 ),
1020 );
1021
1022 foreach ( $dataset_params as $k => $v ) {
1023 $datasets[ $k ]['fillColor'] = sprintf( $v['color1'], '0.2' );
1024 $datasets[ $k ]['strokeColor'] = sprintf( $v['color1'], '1' );
1025 $datasets[ $k ]['pointColor'] = sprintf( $v['color1'], '1' );
1026 $datasets[ $k ]['pointStrokeColor'] = $v['color2'];
1027 $datasets[ $k ]['pointHighlightFill'] = $v['color2'];
1028 $datasets[ $k ]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
1029 $datasets[ $k ]['label'] = $v['label'];
1030 }
1031
1032 return array(
1033 'labels' => $labels,
1034 'datasets' => $datasets,
1035 'sql' => $query,
1036 );
1037 }
1038
1039
1040 /**
1041 * Get data about students to render in chart
1042 *
1043 * @param null $from
1044 * @param null $by
1045 * @param float $time_ago
1046 *
1047 * @return array
1048 */
1049 function learn_press_get_chart_courses( $from = null, $by = null, $time_ago = 0 ) {
1050 global $wpdb;
1051
1052 $labels = array();
1053 $datasets = array();
1054
1055 if ( is_null( $from ) ) {
1056 $from = current_time( 'mysql', 1 );
1057 }
1058
1059 if ( is_null( $by ) ) {
1060 $by = 'days';
1061 }
1062
1063 $results = array(
1064 'all' => array(),
1065 'public' => array(),
1066 'pending' => array(),
1067 'free' => array(),
1068 'paid' => array(),
1069 );
1070
1071 $from_time = is_numeric( $from ) ? $from : strtotime( $from );
1072
1073 switch ( $by ) {
1074 case 'days':
1075 $date_format = 'M d Y';
1076 $_from = - $time_ago + 1;
1077 $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
1078 $_to = date( 'Y-m-d', $from_time );
1079 $_sql_format = '%Y-%m-%d';
1080 $_key_format = 'Y-m-d';
1081 break;
1082 case 'months':
1083 $date_format = 'M Y';
1084 $_from = - $time_ago + 1;
1085 $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
1086 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
1087 $_to = date( 'Y-m-' . $days, $from_time );
1088 $_sql_format = '%Y-%m';
1089 $_key_format = 'Y-m';
1090 break;
1091 case 'years':
1092 $date_format = 'Y';
1093 $_from = - $time_ago + 1;
1094 $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
1095 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
1096 $_to = date( 'Y-12-' . $days, $from_time );
1097 $_sql_format = '%Y';
1098 $_key_format = 'Y';
1099
1100 break;
1101 }
1102
1103 $query_where = '';
1104
1105 if ( current_user_can( LP_TEACHER_ROLE ) ) {
1106 $user_id = learn_press_get_current_user_id();
1107 $query_where .= $wpdb->prepare( ' AND c.post_author=%d ', $user_id );
1108 }
1109
1110 $query = $wpdb->prepare(
1111 "
1112 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
1113 FROM {$wpdb->posts} c
1114 WHERE 1
1115 {$query_where}
1116 AND c.post_status IN('publish', 'pending') AND c.post_type = %s
1117 GROUP BY d
1118 HAVING d BETWEEN %s AND %s
1119 ORDER BY d ASC
1120 ",
1121 $_sql_format,
1122 'lp_course',
1123 $_from,
1124 $_to
1125 );
1126 if ( $_results = $wpdb->get_results( $query ) ) {
1127 foreach ( $_results as $k => $v ) {
1128 $results['all'][ $v->d ] = $v;
1129 }
1130 }
1131 $query = $wpdb->prepare(
1132 "
1133 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
1134 FROM {$wpdb->posts} c
1135 WHERE 1
1136 {$query_where}
1137 AND c.post_status = %s AND c.post_type = %s
1138 GROUP BY d
1139 HAVING d BETWEEN %s AND %s
1140 ORDER BY d ASC
1141 ",
1142 $_sql_format,
1143 'publish',
1144 'lp_course',
1145 $_from,
1146 $_to
1147 );
1148
1149 $_results = $wpdb->get_results( $query );
1150 if ( $_results ) {
1151 foreach ( $_results as $k => $v ) {
1152 $results['publish'][ $v->d ] = $v;
1153 }
1154 }
1155
1156 $query = $wpdb->prepare(
1157 "
1158 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
1159 FROM {$wpdb->posts} c
1160 INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID
1161 WHERE 1
1162 {$query_where}
1163 AND c.post_status = %s AND c.post_type = %s
1164 GROUP BY d
1165 HAVING d BETWEEN %s AND %s
1166 ORDER BY d ASC
1167 ",
1168 $_sql_format,
1169 'publish',
1170 'lp_course',
1171 $_from,
1172 $_to
1173 );
1174
1175 $_results = $wpdb->get_results( $query );
1176 if ( $_results ) {
1177 foreach ( $_results as $k => $v ) {
1178 $results['paid'][ $v->d ] = $v;
1179 }
1180 }
1181
1182 for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
1183 $date = strtotime( "$i $by", $from_time );
1184 $labels[] = date( $date_format, $date );
1185 $key = date( $_key_format, $date );
1186
1187 $all = ! empty( $results['all'][ $key ] ) ? $results['all'][ $key ]->c : 0;
1188 $publish = ! empty( $results['publish'][ $key ] ) ? $results['publish'][ $key ]->c : 0;
1189 $paid = ! empty( $results['paid'][ $key ] ) ? $results['paid'][ $key ]->c : 0;
1190
1191 $datasets[0]['data'][] = $all;
1192 $datasets[1]['data'][] = $publish;
1193 $datasets[2]['data'][] = $all - $publish;
1194 $datasets[3]['data'][] = $paid;
1195 $datasets[4]['data'][] = $all - $paid;
1196 }
1197
1198 $dataset_params = array(
1199 array(
1200 'color1' => 'rgba(47, 167, 255, %s)',
1201 'color2' => '#FFF',
1202 'label' => __( 'All', 'learnpress' ),
1203 ),
1204 array(
1205 'color1' => 'rgba(212, 208, 203, %s)',
1206 'color2' => '#FFF',
1207 'label' => __( 'Publish', 'learnpress' ),
1208 ),
1209 array(
1210 'color1' => 'rgba(234, 199, 155, %s)',
1211 'color2' => '#FFF',
1212 'label' => __( 'Pending', 'learnpress' ),
1213 ),
1214 array(
1215 'color1' => 'rgba(234, 199, 155, %s)',
1216 'color2' => '#FFF',
1217 'label' => __( 'Paid', 'learnpress' ),
1218 ),
1219 array(
1220 'color1' => 'rgba(234, 199, 155, %s)',
1221 'color2' => '#FFF',
1222 'label' => __( 'Free', 'learnpress' ),
1223 ),
1224 );
1225
1226 foreach ( $dataset_params as $k => $v ) {
1227 $datasets[ $k ]['fillColor'] = sprintf( $v['color1'], '0.2' );
1228 $datasets[ $k ]['strokeColor'] = sprintf( $v['color1'], '1' );
1229 $datasets[ $k ]['pointColor'] = sprintf( $v['color1'], '1' );
1230 $datasets[ $k ]['pointStrokeColor'] = $v['color2'];
1231 $datasets[ $k ]['pointHighlightFill'] = $v['color2'];
1232 $datasets[ $k ]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
1233 $datasets[ $k ]['label'] = $v['label'];
1234 }
1235
1236 return array(
1237 'labels' => $labels,
1238 'datasets' => $datasets,
1239 'sql' => $query,
1240 );
1241 }
1242
1243
1244 /**
1245 * Get data about students to render in chart
1246 *
1247 * @param null $from
1248 * @param null $by
1249 * @param float $time_ago
1250 *
1251 * @return array
1252 */
1253 function learn_press_get_chart_orders( $from = null, $by = null, $time_ago = 0 ) {
1254 global $wpdb;
1255 // var_dump( current_user_can(LP_TEACHER_ROLE) );
1256 // exit();
1257 $report_sales_by = learn_press_get_request( 'report_sales_by' );
1258 $course_id = learn_press_get_request( 'course_id' );
1259 $cat_id = learn_press_get_request( 'cat_id' );
1260
1261 $labels = array();
1262 $datasets = array();
1263 if ( is_null( $from ) ) {
1264 $from = current_time( 'mysql', 1 );
1265 }
1266 if ( is_null( $by ) ) {
1267 $by = 'days';
1268 }
1269 $results = array(
1270 'all' => array(),
1271 'completed' => array(),
1272 'pending' => array(),
1273 );
1274 $from_time = is_numeric( $from ) ? $from : strtotime( $from );
1275
1276 switch ( $by ) {
1277 case 'days':
1278 $date_format = 'M d Y';
1279 $_from = - $time_ago + 1;
1280 $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
1281 $_to = date( 'Y-m-d', $from_time );
1282 $_sql_format = '%Y-%m-%d';
1283 $_key_format = 'Y-m-d';
1284 break;
1285 case 'months':
1286 $date_format = 'M Y';
1287 $_from = - $time_ago + 1;
1288 $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
1289 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
1290 $_to = date( 'Y-m-' . $days, $from_time );
1291 $_sql_format = '%Y-%m';
1292 $_key_format = 'Y-m';
1293 break;
1294 case 'years':
1295 $date_format = 'Y';
1296 $_from = - $time_ago + 1;
1297 $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
1298 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
1299 $_to = date( 'Y-12-' . $days, $from_time );
1300 $_sql_format = '%Y';
1301 $_key_format = 'Y';
1302
1303 break;
1304 }
1305
1306 $query_join = '';
1307 $query_where = '';
1308 if ( 'course' === $report_sales_by ) {
1309 $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
1310 . ' ON o.ID=lpoi.order_id '
1311 . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
1312 . ' ON lpoi.order_item_id=loim.learnpress_order_item_id '
1313 . " AND loim.meta_key='_course_id' "
1314 . ' AND CAST(loim.meta_value AS SIGNED)=%d ';
1315 if ( current_user_can( LP_TEACHER_ROLE ) ) {
1316 $user_id = learn_press_get_current_user_id();
1317 $sql_join .= $wpdb->prepare(
1318 ' AND CAST(loim.meta_value AS SIGNED) IN '
1319 . ' ( '
1320 . " SELECT ID FROM {$wpdb->posts} p WHERE p.ID = CAST(loim.meta_value AS SIGNED) AND `post_author`=" . intval( $user_id )
1321 . ' ) '
1322 );
1323 }
1324 $query_join .= $wpdb->prepare( $sql_join, $course_id );
1325
1326 } elseif ( 'category' === $report_sales_by ) {
1327 $sql_join .= " INNER JOIN `{$wpdb->prefix}learnpress_order_items` `lpoi` "
1328 . ' ON o.ID=lpoi.order_id '
1329 . " INNER JOIN {$wpdb->prefix}learnpress_order_itemmeta loim "
1330 . ' ON lpoi.order_item_id=loim.learnpress_order_item_id '
1331 . " AND loim.meta_key='_course_id' "
1332 . ' AND CAST(loim.meta_value AS SIGNED) IN('
1333 // sub query
1334 . ' SELECT tr.object_id '
1335 . " FROM {$wpdb->prefix}term_taxonomy tt INNER JOIN {$wpdb->prefix}term_relationships tr "
1336 . " ON tt.term_taxonomy_id = tr.term_taxonomy_id AND tt.taxonomy='course_category' "
1337 . ' WHERE tt.term_id=%d)';
1338 $query_join .= $wpdb->prepare( $sql_join, $cat_id );
1339 }
1340 if ( current_user_can( LP_TEACHER_ROLE ) ) {
1341 $user_id = learn_press_get_current_user_id();
1342 $query_where .= $wpdb->prepare(
1343 " AND o.ID IN( SELECT oi.order_id
1344 FROM lptest.{$wpdb->prefix}learnpress_order_items oi
1345 inner join {$wpdb->prefix}learnpress_order_itemmeta oim
1346 on oi.order_item_id = oim.learnpress_order_item_id
1347 and oim.meta_key='_course_id'
1348 and cast(oim.meta_value as SIGNED) IN (
1349 SELECT sp.ID FROM {$wpdb->prefix}posts sp WHERE sp.post_author=%d and sp.ID=cast(oim.meta_value as SIGNED)
1350 )
1351 ) ",
1352 $user_id
1353 );
1354 }
1355
1356 $query = $wpdb->prepare(
1357 "
1358 SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
1359 FROM {$wpdb->posts} o {$query_join}
1360 WHERE 1 {$query_where}
1361 AND o.post_status IN('lp-completed') AND o.post_type = %s
1362 GROUP BY d
1363 HAVING d BETWEEN %s AND %s
1364 ORDER BY d ASC
1365 ",
1366 $_sql_format,
1367 'lp_order',
1368 $_from,
1369 $_to
1370 );
1371
1372 if ( $_results = $wpdb->get_results( $query ) ) {
1373 foreach ( $_results as $k => $v ) {
1374 $results['completed'][ $v->d ] = $v;
1375 }
1376 }
1377
1378 $query = $wpdb->prepare(
1379 "
1380 SELECT count(o.ID) as c, DATE_FORMAT( o.post_date, %s) as d
1381 FROM {$wpdb->posts} o {$query_join}
1382 WHERE 1 {$query_where}
1383 AND o.post_status IN('lp-pending', 'lp-processing') AND o.post_type = %s
1384 GROUP BY d
1385 HAVING d BETWEEN %s AND %s
1386 ORDER BY d ASC
1387 ",
1388 $_sql_format,
1389 'lp_order',
1390 $_from,
1391 $_to
1392 );
1393
1394 if ( $_results = $wpdb->get_results( $query ) ) {
1395 foreach ( $_results as $k => $v ) {
1396 $results['pending'][ $v->d ] = $v;
1397 }
1398 }
1399
1400 for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
1401 $date = strtotime( "$i $by", $from_time );
1402 $labels[] = date( $date_format, $date );
1403 $key = date( $_key_format, $date );
1404
1405 $completed = ! empty( $results['completed'][ $key ] ) ? $results['completed'][ $key ]->c : 0;
1406 $pending = ! empty( $results['pending'][ $key ] ) ? $results['pending'][ $key ]->c : 0;
1407 $all = $completed + $pending;
1408
1409 $datasets[0]['data'][] = $all;
1410 $datasets[1]['data'][] = $completed;
1411 $datasets[2]['data'][] = $pending;
1412 }
1413
1414 $dataset_params = array(
1415 array(
1416 'color1' => 'rgba(47, 167, 255, %s)',
1417 'color2' => '#FFF',
1418 'label' => __( 'All', 'learnpress' ),
1419 ),
1420 array(
1421 'color1' => 'rgba(212, 208, 203, %s)',
1422 'color2' => '#FFF',
1423 'label' => __( 'Completed', 'learnpress' ),
1424 ),
1425 array(
1426 'color1' => 'rgba(234, 199, 155, %s)',
1427 'color2' => '#FFF',
1428 'label' => __( 'Pending', 'learnpress' ),
1429 ),
1430 );
1431
1432 foreach ( $dataset_params as $k => $v ) {
1433 $datasets[ $k ]['fillColor'] = sprintf( $v['color1'], '0.2' );
1434 $datasets[ $k ]['strokeColor'] = sprintf( $v['color1'], '1' );
1435 $datasets[ $k ]['pointColor'] = sprintf( $v['color1'], '1' );
1436 $datasets[ $k ]['pointStrokeColor'] = $v['color2'];
1437 $datasets[ $k ]['pointHighlightFill'] = $v['color2'];
1438 $datasets[ $k ]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
1439 $datasets[ $k ]['label'] = $v['label'];
1440 }
1441
1442 return array(
1443 'labels' => $labels,
1444 'datasets' => $datasets,
1445 'sql' => $query,
1446 );
1447 }
1448
1449 /**
1450 * Get data about courses to render in the chart
1451 *
1452 * @return array
1453 */
1454 function learn_press_get_chart_courses2() {
1455 $labels = array(
1456 __( 'Pending Courses/Publish Courses', 'learnpress' ),
1457 __( 'Free Courses/Paid Courses', 'learnpress' ),
1458 );
1459
1460 $datasets = array();
1461 $datasets[0]['data'] = array(
1462 learn_press_get_courses_by_status( 'pending' ),
1463 learn_press_get_courses_by_price( 'free' ),
1464 );
1465
1466 $datasets[1]['data'] = array(
1467 learn_press_get_courses_by_status( 'publish' ),
1468 learn_press_get_courses_by_price( 'not_free' ),
1469 );
1470
1471 $colors = learn_press_get_admin_colors();
1472 $datasets[0]['fillColor'] = $colors[1];
1473 $datasets[0]['strokeColor'] = $colors[1];
1474 $datasets[1]['fillColor'] = $colors[3];
1475 $datasets[1]['strokeColor'] = $colors[3];
1476
1477 return array(
1478 'labels' => $labels,
1479 'datasets' => $datasets,
1480 );
1481 }
1482
1483 /**
1484 * Get colors setting up by admin user
1485 *
1486 * @return array
1487 */
1488 function learn_press_get_admin_colors() {
1489 $admin_color = get_user_meta( get_current_user_id(), 'admin_color', true );
1490 global $_wp_admin_css_colors;
1491 $colors = array();
1492
1493 if ( ! empty( $_wp_admin_css_colors[ $admin_color ]->colors ) ) {
1494 $colors = $_wp_admin_css_colors[ $admin_color ]->colors;
1495 }
1496
1497 if ( empty( $colors[0] ) ) {
1498 $colors[0] = '#000000';
1499 }
1500
1501 if ( empty( $colors[2] ) ) {
1502 $colors[2] = '#00FF00';
1503 }
1504
1505 return $colors;
1506 }
1507
1508 /**
1509 * Convert an array to json format and print out to browser
1510 *
1511 * @param array $chart
1512 */
1513 function learn_press_process_chart( $chart = array() ) {
1514 $data = json_encode(
1515 array(
1516 'labels' => $chart['labels'],
1517 'datasets' => $chart['datasets'],
1518 )
1519 );
1520 echo wp_kses_post( $data );
1521 }
1522
1523 /**
1524 * Print out the configuration for admin chart
1525 */
1526 function learn_press_config_chart() {
1527 $colors = learn_press_get_admin_colors();
1528
1529 $config = array(
1530 'scaleShowGridLines' => true,
1531 'scaleGridLineColor' => '#777',
1532 'scaleGridLineWidth' => 0.3,
1533 'scaleFontColor' => '#444',
1534 'scaleLineColor' => $colors[0],
1535 'bezierCurve' => true,
1536 'bezierCurveTension' => 0.2,
1537 'pointDotRadius' => 5,
1538 'pointDotStrokeWidth' => 5,
1539 'pointHitDetectionRadius' => 20,
1540 'datasetStroke' => true,
1541 'responsive' => true,
1542 'tooltipFillColor' => $colors[2],
1543 'tooltipFontColor' => '#eee',
1544 'tooltipCornerRadius' => 0,
1545 'tooltipYPadding' => 10,
1546 'tooltipXPadding' => 10,
1547 'barDatasetSpacing' => 10,
1548 'barValueSpacing' => 200,
1549
1550 );
1551
1552 echo json_encode( $config );
1553 }
1554
1555 function set_post_order_in_admin( $wp_query ) {
1556 global $pagenow;
1557
1558 if ( isset( $_GET['post_type'] ) ) {
1559 $post_type = LP_Helper::sanitize_params_submitted( $_GET['post_type'] );
1560 } else {
1561 $post_type = '';
1562 }
1563
1564 if ( is_admin() && 'edit.php' == $pagenow && $post_type == LP_COURSE_CPT && ! isset( $_GET['orderby'] ) ) {
1565 $wp_query->set( 'orderby', 'date' );
1566 $wp_query->set( 'order', 'DSC' );
1567 }
1568 }
1569
1570 // add_filter( 'pre_get_posts', 'set_post_order_in_admin' );
1571
1572 function learn_press_copy_post_meta( $from_id, $to_id ) {
1573 global $wpdb;
1574
1575 $course_meta = $wpdb->get_results(
1576 $wpdb->prepare( "SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id = %d", $from_id )
1577 );
1578
1579 if ( count( $course_meta ) != 0 ) {
1580 $sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
1581 $sql_query_sel = array();
1582
1583 foreach ( $course_meta as $meta ) {
1584 $meta_key = $meta->meta_key;
1585 $meta_value = addslashes( $meta->meta_value );
1586
1587 $sql_query_sel[] = "SELECT {$to_id}, '$meta_key', '$meta_value'";
1588 }
1589
1590 $sql_query .= implode( ' UNION ALL ', $sql_query_sel );
1591 $wpdb->query( $sql_query );
1592 }
1593 }
1594
1595 /**
1596 * Check to see if a plugin is already installed or not
1597 *
1598 * @param $plugin
1599 *
1600 * @return bool
1601 */
1602 function learn_press_is_plugin_install( $plugin ) {
1603 $installed_plugins = get_plugins();
1604
1605 return isset( $installed_plugins[ $plugin ] );
1606 }
1607
1608 /**
1609 * Get plugin file that contains the information from slug
1610 *
1611 * @param $slug
1612 *
1613 * @return mixed
1614 */
1615 function learn_press_plugin_basename_from_slug( $slug ) {
1616 $keys = array_keys( get_plugins() );
1617
1618 foreach ( $keys as $key ) {
1619 if ( preg_match( '|^' . $slug . '/|', $key ) ) {
1620 return $key;
1621 }
1622 }
1623
1624 return $slug;
1625 }
1626
1627 function learn_press_request_query( $vars = array() ) {
1628 global $typenow, $wp_query, $wp_post_statuses;
1629
1630 if ( LP_ORDER_CPT === $typenow ) {
1631 if ( ! isset( $vars['post_status'] ) ) {
1632 $post_statuses = learn_press_get_order_statuses();
1633
1634 foreach ( $post_statuses as $status => $value ) {
1635 if ( isset( $wp_post_statuses[ $status ] ) && false === $wp_post_statuses[ $status ]->show_in_admin_all_list ) {
1636 unset( $post_statuses[ $status ] );
1637 }
1638 }
1639
1640 $vars['post_status'] = array_keys( $post_statuses );
1641
1642 }
1643 }
1644
1645 return $vars;
1646 }
1647
1648 add_filter( 'request', 'learn_press_request_query', 0 );
1649
1650 function _learn_press_reset_course_data() {
1651 if ( empty( $_REQUEST['reset-course-data'] ) ) {
1652 return false;
1653 }
1654
1655 learn_press_reset_course_data( intval( $_REQUEST['reset-course-data'] ) );
1656
1657 wp_redirect( esc_url_raw( remove_query_arg( 'reset-course-data' ) ) );
1658 }
1659
1660 add_action( 'init', '_learn_press_reset_course_data' );
1661
1662 function learn_press_admin_section_loop_item_class( $item, $section ) {
1663 $classes = array(
1664 'lp-section-item',
1665 );
1666
1667 $classes[] = 'lp-item-' . $item->post_type;
1668
1669 if ( ! absint( $item->ID ) ) {
1670 $classes[] = 'lp-item-empty lp-item-new focus';
1671 }
1672
1673 $classes = apply_filters( 'learn_press_section_loop_item_class', $classes, $item, $section );
1674
1675 if ( $classes ) {
1676 echo 'class="' . join( ' ', $classes ) . '"';
1677 }
1678
1679 return $classes;
1680 }
1681
1682 function learn_press_disable_checked_ontop( $args ) {
1683
1684 if ( 'course_category' == $args['taxonomy'] ) {
1685 $args['checked_ontop'] = false;
1686 }
1687
1688 return $args;
1689 }
1690
1691 add_filter( 'wp_terms_checklist_args', 'learn_press_disable_checked_ontop' );
1692
1693 function learn_press_get_screens() {
1694 $screen_id = sanitize_title( __( 'LearnPress', 'learnpress' ) );
1695
1696 $screens = array(
1697 'toplevel_page_' . $screen_id,
1698 $screen_id . '_page_learn-press-statistics',
1699 $screen_id . '_page_learn-press-addons',
1700 $screen_id . '_page_learn-press-settings',
1701 $screen_id . '_page_learn-press-tools',
1702 );
1703
1704 foreach ( array( LP_COURSE_CPT, LP_LESSON_CPT, LP_QUIZ_CPT, LP_QUESTION_CPT, LP_ORDER_CPT ) as $post_type ) {
1705 $screens[] = 'edit-' . $post_type;
1706 $screens[] = $post_type;
1707 }
1708
1709 return apply_filters( 'learn_press_screen_ids', $screens );
1710 }
1711
1712 function learn_press_is_post_type_screen( $post_type, $union = 'OR' ) {
1713 if ( is_array( $post_type ) ) {
1714 $return = null;
1715
1716 foreach ( $post_type as $_post_type ) {
1717 $check = learn_press_is_post_type_screen( $_post_type );
1718
1719 if ( $union == 'OR' && $check ) {
1720 return true;
1721 }
1722
1723 if ( $return == null ) {
1724 $return = $check;
1725 } else {
1726 $return = $return && $check;
1727 }
1728
1729 if ( $union !== 'OR' ) {
1730 return $return;
1731 }
1732 }
1733
1734 return $return;
1735 }
1736
1737 $screen = get_current_screen();
1738
1739 if ( ! $screen ) {
1740 return;
1741 }
1742
1743 $screen_id = $screen->id;
1744
1745 return in_array( $screen_id, array( $post_type, "edit-{$post_type}" ) );
1746 }
1747
1748 function learn_press_get_notice_dismiss( $context, $type = 'transient' ) {
1749 if ( $type == 'transient' ) {
1750 return get_transient( 'learn_press_dismiss_notice_' . $context );
1751 }
1752
1753 return get_option( 'learn_press_dismiss_notice_' . $context );
1754 }
1755
1756 if ( ! function_exists( 'learn_press_course_insert_section' ) ) {
1757 function learn_press_course_insert_section( $section = array() ) {
1758 global $wpdb;
1759
1760 $section = wp_parse_args(
1761 $section,
1762 array(
1763 'section_name' => '',
1764 'section_course_id' => 0,
1765 'section_order' => 0,
1766 'section_description' => '',
1767 )
1768 );
1769
1770 $section = stripslashes_deep( $section );
1771
1772 extract( $section );
1773
1774 $insert_data = compact( 'section_name', 'section_course_id', 'section_order', 'section_description' );
1775
1776 $wpdb->insert(
1777 $wpdb->learnpress_sections,
1778 $insert_data,
1779 array( '%s', '%d', '%d' )
1780 );
1781
1782 return $wpdb->insert_id;
1783 }
1784 }
1785
1786 if ( ! function_exists( 'learn_press_course_insert_section_item' ) ) {
1787 function learn_press_course_insert_section_item( $item_data = array() ) {
1788 global $wpdb;
1789
1790 $wpdb->insert(
1791 $wpdb->learnpress_section_items,
1792 array(
1793 'section_id' => $item_data['section_id'],
1794 'item_id' => $item_data['item_id'],
1795 'item_order' => $item_data['item_order'],
1796 'item_type' => $item_data['item_type'],
1797 ),
1798 array(
1799 '%d',
1800 '%d',
1801 '%d',
1802 '%s',
1803 )
1804 );
1805
1806 return $wpdb->insert_id;
1807 }
1808 }
1809
1810 if ( ! function_exists( 'learn_press_duplicate_post' ) ) {
1811 /**
1812 * Duplicate post.
1813 *
1814 * @param null $post_id
1815 * @param array $args
1816 * @param bool $meta
1817 *
1818 * @return bool|mixed
1819 * @since 3.0.0
1820 */
1821 function learn_press_duplicate_post( $post_id = null, $args = array(), $meta = true ) {
1822 $post = get_post( $post_id );
1823
1824 if ( ! $post ) {
1825 return false;
1826 }
1827
1828 $default = array(
1829 'comment_status' => $post->comment_status,
1830 'ping_status' => $post->ping_status,
1831 'post_author' => get_current_user_id(),
1832 'post_content' => $post->post_content,
1833 'post_excerpt' => $post->post_excerpt,
1834 'post_parent' => $post->post_parent,
1835 'post_password' => $post->post_password,
1836 'post_status' => 'draft',
1837 'post_title' => $post->post_title . __( 'Copy', 'learnpress' ),
1838 'post_type' => $post->post_type,
1839 'to_ping' => $post->to_ping,
1840 'menu_order' => $post->menu_order,
1841 'exclude_meta' => array(),
1842 );
1843
1844 $args = wp_parse_args( $args, $default );
1845 $exclude_meta = array();
1846
1847 if ( ! empty( $args['exclude_meta'] ) ) {
1848 $exclude_meta = $args['exclude_meta'];
1849 unset( $args['exclude_meta'] );
1850 }
1851
1852 $new_post_id = wp_insert_post( $args );
1853
1854 if ( ! is_wp_error( $new_post_id ) && $meta ) {
1855 learn_press_duplicate_post_meta( $post_id, $new_post_id, $exclude_meta );
1856
1857 $taxonomies = get_object_taxonomies( $post->post_type );
1858
1859 foreach ( $taxonomies as $taxonomy ) {
1860 $post_terms = wp_get_object_terms( $post_id, $taxonomy, array( 'fields' => 'slugs' ) );
1861 wp_set_object_terms( $new_post_id, $post_terms, $taxonomy, false );
1862 }
1863 }
1864
1865 return apply_filters( 'learn_press_duplicate_post', $new_post_id, $post_id );
1866 }
1867 }
1868
1869 /**
1870 * Duplicate post meta.
1871 *
1872 * @editor tungnx
1873 * @sicne 3.0.0
1874 * @version 4.0.1
1875 */
1876 if ( ! function_exists( 'learn_press_duplicate_post_meta' ) ) {
1877 function learn_press_duplicate_post_meta( $old_post_id, $new_post_id, $excerpt = array() ) {
1878 $lp_db = LP_Database::getInstance();
1879
1880 try {
1881 $excerpt = array_merge( array( '_edit_lock', '_edit_last' ), $excerpt );
1882 $excerpt_name_keys = implode( "','", $excerpt );
1883 $sql_query = $lp_db->wpdb->prepare(
1884 "INSERT INTO $lp_db->tb_postmeta (post_id, meta_key, meta_value)
1885 SELECT %d, pmc.meta_key, pmc.meta_value
1886 FROM $lp_db->tb_postmeta AS pmc
1887 WHERE post_id = %d
1888 AND meta_key not in ('{$excerpt_name_keys}')
1889 ",
1890 $new_post_id,
1891 $old_post_id
1892 );
1893
1894 $lp_db->check_execute_has_error();
1895
1896 $lp_db->wpdb->query( $sql_query );
1897 } catch ( Throwable $e ) {
1898 error_log( $e->getMessage() );
1899 }
1900 }
1901 }
1902
1903 if ( ! function_exists( 'learn_press_sort_questions' ) ) {
1904 function learn_press_sort_questions( $types ) {
1905 $user_id = get_current_user_id();
1906 $question_types = get_user_meta( $user_id, '_learn_press_memorize_question_types', true );
1907
1908 if ( ! empty( $question_types ) ) {
1909 $sort = array();
1910 arsort( $types );
1911 $new_types = array();
1912 $ktypes = array_keys( $types );
1913
1914 for ( $i = 0; $i < count( $ktypes ) - 1; $i ++ ) {
1915 $max = $i;
1916
1917 if ( ! isset( $question_types[ $ktypes[ $i ] ] ) ) {
1918 $question_types[ $ktypes[ $i ] ] = 0;
1919 }
1920
1921 for ( $j = $i + 1; $j < count( $ktypes ); $j ++ ) {
1922 if ( isset( $question_types[ $ktypes[ $j ] ], $question_types[ $ktypes[ $max ] ] )
1923 && $question_types[ $ktypes[ $j ] ] > $question_types[ $ktypes[ $max ] ]
1924 ) {
1925 $max = $j;
1926 }
1927 }
1928
1929 $tmp = $ktypes[ $i ];
1930 $ktypes[ $i ] = $ktypes[ $max ];
1931 $ktypes[ $max ] = $tmp;
1932 }
1933
1934 $ktypes = array_flip( $ktypes );
1935 $types = array_merge( $ktypes, $types );
1936 }
1937
1938 return $types;
1939 }
1940 }
1941
1942 if ( ! function_exists( 'learn_press_duplicate_question' ) ) {
1943 function learn_press_duplicate_question( $question_id = null, $quiz_id = null, $args = array() ) {
1944 if ( ! $question_id || ! get_post( $question_id ) ) {
1945 return new WP_Error( sprintf( __( 'Question id %s does not exist.', 'learnpress' ), $question_id ) );
1946 }
1947
1948 if ( $quiz_id && ! get_post( $quiz_id ) ) {
1949 return new WP_Error( sprintf( __( 'Quiz id %s does not exist.', 'learnpress' ), $quiz_id ) );
1950 }
1951
1952 global $wpdb;
1953 $new_question_id = learn_press_duplicate_post( $question_id, $args );
1954
1955 if ( $quiz_id ) {
1956 $sql = $wpdb->prepare(
1957 "
1958 SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
1959 ",
1960 $quiz_id,
1961 $question_id
1962 );
1963
1964 $quiz_question_data = $wpdb->get_row( $sql );
1965 $max_order = $wpdb->get_var(
1966 $wpdb->prepare(
1967 "SELECT max(question_order) FROM {$wpdb->prefix}learnpress_quiz_questions WHERE quiz_id = %d",
1968 $quiz_id
1969 )
1970 );
1971
1972 if ( $quiz_question_data ) {
1973 $wpdb->insert(
1974 $wpdb->learnpress_quiz_questions,
1975 array(
1976 'quiz_id' => $quiz_id,
1977 'question_id' => $new_question_id,
1978 'question_order' => $max_order + 1,
1979 'params' => $quiz_question_data->params,
1980 ),
1981 array(
1982 '%d',
1983 '%d',
1984 '%d',
1985 '%s',
1986 )
1987 );
1988 }
1989 }
1990
1991 $sql = $wpdb->prepare(
1992 "
1993 SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
1994 ",
1995 $question_id
1996 );
1997
1998 $question_answers = $wpdb->get_results( $sql );
1999
2000 if ( $question_answers ) {
2001 foreach ( $question_answers as $q_a ) {
2002 $wpdb->insert(
2003 $wpdb->learnpress_question_answers,
2004 array(
2005 'question_id' => $new_question_id,
2006 'title' => $q_a->title,
2007 'value' => $q_a->value,
2008 'is_true' => $q_a->is_true,
2009 'order' => $q_a->order,
2010 ),
2011 array(
2012 '%d',
2013 '%s',
2014 '%s',
2015 )
2016 );
2017 }
2018 }
2019
2020 return $new_question_id;
2021 }
2022 }
2023
2024 if ( ! function_exists( 'learn_press_duplicate_quiz' ) ) {
2025
2026 function learn_press_duplicate_quiz( $quiz_id = null, $args = array() ) {
2027 global $wpdb;
2028
2029 $new_quiz_id = learn_press_duplicate_post( $quiz_id, $args, true );
2030 $quiz = LP_Quiz::get_quiz( $quiz_id );
2031 if ( ! $quiz ) {
2032 return 0;
2033 }
2034
2035 $questions = $quiz->get_question_ids();
2036
2037 if ( $questions ) {
2038 foreach ( $questions as $question_id ) {
2039 $new_question_id = learn_press_duplicate_post( $question_id );
2040
2041 $sql = $wpdb->prepare(
2042 "
2043 SELECT * FROM $wpdb->learnpress_quiz_questions WHERE quiz_id = %d AND question_id = %d
2044 ",
2045 $quiz_id,
2046 $question_id
2047 );
2048
2049 $quiz_question_data = $wpdb->get_row( $sql );
2050
2051 if ( $quiz_question_data ) {
2052 $wpdb->insert(
2053 $wpdb->learnpress_quiz_questions,
2054 array(
2055 'quiz_id' => $new_quiz_id,
2056 'question_id' => $new_question_id,
2057 'question_order' => $quiz_question_data->question_order,
2058 'params' => $quiz_question_data->params,
2059 ),
2060 array(
2061 '%d',
2062 '%d',
2063 '%d',
2064 '%s',
2065 )
2066 );
2067 }
2068
2069 $sql = $wpdb->prepare(
2070 "
2071 SELECT * FROM $wpdb->learnpress_question_answers WHERE question_id = %d
2072 ",
2073 $question_id
2074 );
2075
2076 $question_answers = $wpdb->get_results( $sql );
2077 if ( $question_answers ) {
2078 foreach ( $question_answers as $q_a ) {
2079 $wpdb->insert(
2080 $wpdb->learnpress_question_answers,
2081 array(
2082 'question_id' => $new_question_id,
2083 'title' => $q_a->title,
2084 'value' => $q_a->value,
2085 'is_true' => $q_a->is_true,
2086 'order' => $q_a->order,
2087 ),
2088 array(
2089 '%d',
2090 '%s',
2091 '%s',
2092 )
2093 );
2094 }
2095 }
2096 }
2097 }
2098
2099 return $new_quiz_id;
2100 }
2101 }
2102
2103 /**
2104 * Get general data to render in chart
2105 *
2106 * @param null $from
2107 * @param null $by
2108 * @param float $time_ago
2109 *
2110 * @return array
2111 */
2112 function learn_press_get_chart_general( $from = null, $by = null, $time_ago = 0 ) {
2113 global $wpdb;
2114
2115 $labels = array();
2116 $datasets = array();
2117
2118 if ( is_null( $from ) ) {
2119 $from = current_time( 'mysql', 1 );
2120 }
2121
2122 if ( is_null( $by ) ) {
2123 $by = 'days';
2124 }
2125
2126 $results = array(
2127 'all' => array(),
2128 'public' => array(),
2129 'pending' => array(),
2130 'free' => array(),
2131 'paid' => array(),
2132 );
2133
2134 $results = array(
2135 'course' => array(),
2136 'lesson' => array(),
2137 'quiz' => array(),
2138 'student' => array(),
2139 'teacher' => array(),
2140 'revenue' => array(),
2141 );
2142
2143 $from_time = is_numeric( $from ) ? $from : strtotime( $from );
2144 $_from = '';
2145 $_to = '';
2146 $_sql_format = '';
2147 $date_format = '';
2148
2149 switch ( $by ) {
2150 case 'days':
2151 $date_format = 'M d Y';
2152 $_from = - $time_ago + 1;
2153 $_from = date( 'Y-m-d', strtotime( "{$_from} {$by}", $from_time ) );
2154 $_to = date( 'Y-m-d', $from_time );
2155 $_sql_format = '%Y-%m-%d';
2156 $_key_format = 'Y-m-d';
2157 break;
2158
2159 case 'months':
2160 $date_format = 'M Y';
2161 $_from = - $time_ago + 1;
2162 $_from = date( 'Y-m-01', strtotime( "{$_from} {$by}", $from_time ) );
2163 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
2164 $_to = date( 'Y-m-' . $days, $from_time );
2165 $_sql_format = '%Y-%m';
2166 $_key_format = 'Y-m';
2167 break;
2168
2169 case 'years':
2170 $date_format = 'Y';
2171 $_from = - $time_ago + 1;
2172 $_from = date( 'Y-01-01', strtotime( "{$_from} {$by}", $from_time ) );
2173 $days = date( 't', mktime( 0, 0, 0, date( 'm', $from_time ), 1, date( 'Y', $from_time ) ) );
2174 $_to = date( 'Y-12-' . $days, $from_time );
2175 $_sql_format = '%Y';
2176 $_key_format = 'Y';
2177 break;
2178
2179 }
2180
2181 $query_where = '';
2182 if ( current_user_can( LP_TEACHER_ROLE ) ) {
2183 $user_id = learn_press_get_current_user_id();
2184 $query_where .= $wpdb->prepare( ' AND c.post_author=%d ', $user_id );
2185 }
2186
2187 $query = $wpdb->prepare(
2188 "
2189 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
2190 FROM {$wpdb->posts} c
2191 WHERE 1
2192 {$query_where}
2193 AND c.post_status IN('publish', 'pending') AND c.post_type = %s
2194 GROUP BY d
2195 HAVING d BETWEEN %s AND %s
2196 ORDER BY d ASC
2197 ",
2198 $_sql_format,
2199 'lp_course',
2200 $_from,
2201 $_to
2202 );
2203
2204 if ( $_results = $wpdb->get_results( $query ) ) {
2205 foreach ( $_results as $k => $v ) {
2206 $results['all'][ $v->d ] = $v;
2207 }
2208 }
2209
2210 $query = $wpdb->prepare(
2211 "
2212 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
2213 FROM {$wpdb->posts} c
2214 WHERE 1
2215 {$query_where}
2216 AND c.post_status = %s AND c.post_type = %s
2217 GROUP BY d
2218 HAVING d BETWEEN %s AND %s
2219 ORDER BY d ASC
2220 ",
2221 $_sql_format,
2222 'publish',
2223 'lp_course',
2224 $_from,
2225 $_to
2226 );
2227
2228 if ( $_results = $wpdb->get_results( $query ) ) {
2229 foreach ( $_results as $k => $v ) {
2230 $results['publish'][ $v->d ] = $v;
2231 }
2232 }
2233
2234 $query = $wpdb->prepare(
2235 "
2236 SELECT count(c.ID) as c, DATE_FORMAT( c.post_date, %s) as d
2237 FROM {$wpdb->posts} c
2238 INNER JOIN {$wpdb->postmeta} cm ON cm.post_id = c.ID
2239 WHERE 1
2240 {$query_where}
2241 AND c.post_status = %s AND c.post_type = %s
2242 GROUP BY d
2243 HAVING d BETWEEN %s AND %s
2244 ORDER BY d ASC
2245 ",
2246 $_sql_format,
2247 'publish',
2248 'lp_course',
2249 $_from,
2250 $_to
2251 );
2252
2253 if ( $_results = $wpdb->get_results( $query ) ) {
2254 foreach ( $_results as $k => $v ) {
2255 $results['paid'][ $v->d ] = $v;
2256 }
2257 }
2258
2259 for ( $i = - $time_ago + 1; $i <= 0; $i ++ ) {
2260 $date = strtotime( "$i $by", $from_time );
2261 $labels[] = date( $date_format, $date );
2262 $key = date( $_key_format, $date );
2263
2264 $all = ! empty( $results['all'][ $key ] ) ? $results['all'][ $key ]->c : 0;
2265 $publish = ! empty( $results['publish'][ $key ] ) ? $results['publish'][ $key ]->c : 0;
2266 $paid = ! empty( $results['paid'][ $key ] ) ? $results['paid'][ $key ]->c : 0;
2267
2268 $datasets[0]['data'][] = $all;
2269 $datasets[1]['data'][] = $publish;
2270 $datasets[2]['data'][] = $all - $publish;
2271 $datasets[3]['data'][] = $paid;
2272 $datasets[4]['data'][] = $all - $paid;
2273 }
2274
2275 $dataset_params = array(
2276 array(
2277 'color1' => 'rgba(47, 167, 255, %s)',
2278 'color2' => '#FFF',
2279 'label' => __( 'All', 'learnpress' ),
2280 ),
2281 array(
2282 'color1' => 'rgba(212, 208, 203, %s)',
2283 'color2' => '#FFF',
2284 'label' => __( 'Publish', 'learnpress' ),
2285 ),
2286 array(
2287 'color1' => 'rgba(234, 199, 155, %s)',
2288 'color2' => '#FFF',
2289 'label' => __( 'Pending', 'learnpress' ),
2290 ),
2291 array(
2292 'color1' => 'rgba(234, 199, 155, %s)',
2293 'color2' => '#FFF',
2294 'label' => __( 'Paid', 'learnpress' ),
2295 ),
2296 array(
2297 'color1' => 'rgba(234, 199, 155, %s)',
2298 'color2' => '#FFF',
2299 'label' => __( 'Free', 'learnpress' ),
2300 ),
2301 );
2302
2303 foreach ( $dataset_params as $k => $v ) {
2304 $datasets[ $k ]['fillColor'] = sprintf( $v['color1'], '0.2' );
2305 $datasets[ $k ]['strokeColor'] = sprintf( $v['color1'], '1' );
2306 $datasets[ $k ]['pointColor'] = sprintf( $v['color1'], '1' );
2307 $datasets[ $k ]['pointStrokeColor'] = $v['color2'];
2308 $datasets[ $k ]['pointHighlightFill'] = $v['color2'];
2309 $datasets[ $k ]['pointHighlightStroke'] = sprintf( $v['color1'], '1' );
2310 $datasets[ $k ]['label'] = $v['label'];
2311 }
2312
2313 return array(
2314 'labels' => $labels,
2315 'datasets' => $datasets,
2316 'sql' => $query,
2317 );
2318 }
2319
2320 function learn_press_get_default_section( $section = null ) {
2321 if ( ! $section ) {
2322 $section = new stdClass();
2323 }
2324 foreach (
2325 array(
2326 'section_id' => null,
2327 'section_name' => '',
2328 'section_course_id' => null,
2329 'section_order' => null,
2330 'section_description' => '',
2331 ) as $k => $v
2332 ) {
2333 if ( ! property_exists( $section, $k ) ) {
2334 $section->{$k} = $v;
2335 }
2336 }
2337
2338 return $section;
2339 }
2340
2341 /**
2342 * Display time fields for a post in editing mode.
2343 *
2344 * @param int $edit
2345 * @param int $for_post
2346 * @param int $tab_index
2347 * @param int $multi
2348 */
2349 function learn_press_touch_time( $edit = 1, $for_post = 1, $tab_index = 0, $multi = 0 ) {
2350 global $wp_locale;
2351 $post = get_post();
2352
2353 if ( $for_post ) {
2354 $edit = ! ( in_array(
2355 $post->post_status,
2356 array(
2357 'draft',
2358 'pending',
2359 )
2360 ) && ( ! $post->post_date_gmt || '0000-00-00 00:00:00' == $post->post_date_gmt ) );
2361 }
2362
2363 $tab_index_attribute = '';
2364 if ( (int) $tab_index > 0 ) {
2365 $tab_index_attribute = " tabindex=\"$tab_index\"";
2366 }
2367
2368 $time_adj = current_time( 'timestamp' );
2369 $post_date = ( $for_post ) ? $post->post_date : get_comment()->comment_date;
2370 $jj = ( $edit ) ? mysql2date( 'd', $post_date, false ) : gmdate( 'd', $time_adj );
2371 $mm = ( $edit ) ? mysql2date( 'm', $post_date, false ) : gmdate( 'm', $time_adj );
2372 $aa = ( $edit ) ? mysql2date( 'Y', $post_date, false ) : gmdate( 'Y', $time_adj );
2373 $hh = ( $edit ) ? mysql2date( 'H', $post_date, false ) : gmdate( 'H', $time_adj );
2374 $mn = ( $edit ) ? mysql2date( 'i', $post_date, false ) : gmdate( 'i', $time_adj );
2375 $ss = ( $edit ) ? mysql2date( 's', $post_date, false ) : gmdate( 's', $time_adj );
2376
2377 $cur_jj = gmdate( 'd', $time_adj );
2378 $cur_mm = gmdate( 'm', $time_adj );
2379 $cur_aa = gmdate( 'Y', $time_adj );
2380 $cur_hh = gmdate( 'H', $time_adj );
2381 $cur_mn = gmdate( 'i', $time_adj );
2382
2383 $map = array(
2384 'mm' => array( $mm, $cur_mm ),
2385 'jj' => array( $jj, $cur_jj ),
2386 'aa' => array( $aa, $cur_aa ),
2387 'hh' => array( $hh, $cur_hh ),
2388 'mn' => array( $mn, $cur_mn ),
2389 );
2390
2391 foreach ( $map as $timeunit => $value ) {
2392 list( $unit, $curr ) = $value;
2393
2394 echo '<input type="hidden" id="hidden_' . $timeunit . '" name="hidden_' . $timeunit . '" value="' . $unit . '" />' . "\n";
2395 $cur_timeunit = 'cur_' . $timeunit;
2396 echo '<input type="hidden" id="' . $cur_timeunit . '" name="' . $cur_timeunit . '" value="' . $curr . '" />' . "\n";
2397 }
2398 }
2399
2400 /**
2401 * Filter to modal search items to void filter the posts by author.
2402 *
2403 * @param int|string $context_id
2404 * @param string $context
2405 *
2406 * @return bool|int|string
2407 * @since 3.0.4
2408 */
2409 function learn_press_modal_search_items_context( $context_id, $context ) {
2410 if ( 'order-items' === $context ) {
2411 $context_id = false;
2412 }
2413
2414 return $context_id;
2415 }
2416
2417 add_filter( 'learn-press/modal-search-items/context-id', 'learn_press_modal_search_items_context', 10, 2 );
2418
2419 /**
2420 * Sync post meta when saving post type.
2421 *
2422 * @param int $post_id
2423 *
2424 * @since 3.2.0
2425 * @editor tungnx
2426 * @modify 1.4.1 - comment - not use
2427 */
2428 /*function learn_press_maybe_sync_data( $post_id ) {
2429 $post_type = get_post_type( $post_id );
2430
2431 switch ( $post_type ) {
2432 case LP_COURSE_CPT:
2433 LP_Repair_Database::instance()->sync_user_courses();
2434 break;
2435 case LP_LESSON_CPT:
2436 break;
2437 case LP_QUIZ_CPT:
2438 break;
2439 default:
2440 }
2441 }*/
2442
2443 //add_action( 'save_post', 'learn_press_maybe_sync_data' );
2444
2445 /**
2446 * Return id of current screen.
2447 *
2448 * @return bool|string
2449 * @since 3.2.6
2450 */
2451 function learn_press_get_screen_id() {
2452 $screen = get_current_screen();
2453 $screen_id = $screen ? $screen->id : false;
2454
2455 return $screen_id;
2456 }
2457
2458 /**
2459 * Check if current screen is a page of LP or
2460 * editing post type of LP such as course, lesson, etc...
2461 *
2462 * @return bool
2463 * @since 3.2.6
2464 */
2465 /*
2466 function learn_press_is_admin_page() {
2467 $screen_id = learn_press_get_screen_id();
2468 $is_learnpress = false;
2469
2470 $post_types = apply_filters(
2471 'learn-press/admin-post-type-pages',
2472 array( LP_COURSE_CPT, LP_QUIZ_CPT, LP_LESSON_CPT, LP_QUESTION_CPT, LP_ORDER_CPT, 'lp_cert', 'lp_assignment' )
2473 );
2474 foreach ( $post_types as $post_type ) {
2475 if ( in_array( $screen_id, array( "edit-{$post_type}", $post_type ) ) ) {
2476 $is_learnpress = true;
2477 break;
2478 }
2479 }
2480
2481 if ( strpos( $screen_id, 'learnpress_page_' ) === 0 ) {
2482 $is_learnpress = true;
2483 }
2484
2485 return apply_filters( 'learn-press/is-admin-page', $is_learnpress, $screen_id );
2486 }*/
2487
2488 function learn_press_get_orders_status_chart_data() {
2489 $data = array(
2490 'type' => 'pie',
2491 'data' => array(
2492 'labels' => array(),
2493 'datasets' => array(
2494 array(
2495 'label' => '# of Votes',
2496 'data' => array(),
2497 'backgroundColor' => array(
2498 'rgba(54, 162, 235, 0.2)',
2499 'rgba(255, 206, 86, 0.2)',
2500 'rgba(75, 192, 192, 0.2)',
2501 'rgba(153, 102, 255, 0.2)',
2502 'rgba(255, 159, 64, 0.2)',
2503 ),
2504 'borderColor' => array(
2505 'rgba(54, 162, 235, 1)',
2506 'rgba(255, 206, 86, 1)',
2507 'rgba(75, 192, 192, 1)',
2508 'rgba(153, 102, 255, 1)',
2509 'rgba(255, 159, 64, 1)',
2510 ),
2511 'borderWidth' => 1,
2512 ),
2513 ),
2514 ),
2515 'options' => array(
2516 'scales' => array(
2517 'yAxes' => array(
2518 array(
2519 'ticks' => array(
2520 'beginAtZero' => true,
2521 ),
2522 ),
2523 ),
2524 ),
2525 ),
2526 );
2527
2528 $order_statuses = learn_press_get_order_statuses( true, true );
2529 $specific_statuses = array( 'lp-completed', 'lp-failed' );
2530
2531 foreach ( $order_statuses as $status ) {
2532 if ( ! in_array( $status, $specific_statuses ) ) {
2533 $specific_statuses[] = $status;
2534 }
2535 }
2536
2537 $labels = learn_press_get_order_statuses();
2538 $counts = learn_press_count_orders( array( 'status' => $specific_statuses ) );
2539
2540 foreach ( $counts as $k => $v ) {
2541 $data['data']['labels'][] = isset( $labels[ $k ] ) ? $labels[ $k ] : 'Untitled';
2542 $data['data']['datasets'][0]['data'][] = $v;
2543 }
2544
2545 return $data;
2546 }
2547
2548 require_once 'class-lp-post-type-actions.php';
2549