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