PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.1
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.1
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 4.2.1 All 138 releases
learnpress / inc / admin / class-lp-install-sample-data.php

class-lp-install-sample-data.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.1, at inc/admin/class-lp-install-sample-data.php

737 lines 17.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 use LearnPress\Models\CourseModel;
4 use LearnPress\Models\CoursePostModel;
5 use LearnPress\Services\CourseService;
6
7 /**
8 * Class LP_Install_Sample_Data
9 *
10 * Create sample course for testing purpose.
11 * This will create sections, items, questions, answers, ...
12 *
13 * @since 3.0.0
14 */
15 class LP_Install_Sample_Data {
16
17 /**
18 * @var array
19 */
20 public static $section_range = array( 3, 3 );
21
22 /**
23 * @var array
24 */
25 public static $item_range = array( 5, 10 );
26
27 /**
28 * @var array
29 */
30 public static $question_range = array( 2, 5 );
31
32 /**
33 * @var array
34 */
35 public static $answer_range = array( 2, 5 );
36
37 /**
38 * @var int
39 */
40 public static $max_content_paragraph = 5;
41
42 /**
43 * @var string
44 */
45 protected $dummy_text = '';
46
47 /**
48 * LP_Install_Sample_Data constructor.
49 */
50 public function __construct() {
51 add_filter( 'learn-press/script-data', array( $this, 'i18n' ), 10, 2 );
52
53 $actions = array(
54 'lp-install-sample-data',
55 'lp-uninstall-sample-data',
56 );
57
58 if ( ! in_array( LP_Request::get_param( 'page' ), $actions ) ) {
59 return;
60 }
61
62 add_action( 'init', array( $this, 'install' ) );
63 add_action( 'init', array( $this, 'uninstall' ) );
64 }
65
66 public function i18n( $data, $handle ) {
67 if ( 'learn-press-global' !== $handle ) {
68 return $data;
69 }
70
71 $i18n = array(
72 'confirm_install_sample_data' => esc_html__( 'Are you sure you want to install the sample course data?', 'learnpress' ),
73 'confirm_uninstall_sample_data' => esc_html__( 'Are you sure you want to delete the sample course data?', 'learnpress' ),
74 );
75
76 if ( empty( $data['i18n'] ) ) {
77 $data['i18n'] = $i18n;
78 } else {
79 $data['i18n'] = array_merge( $data['i18n'], $i18n );
80 }
81
82 return $data;
83 }
84
85 /**
86 * Install
87 *
88 * @TODO - Need write to api, not hook init.
89 */
90 public function install() {
91 if ( ! wp_verify_nonce( LP_Request::get_param( '_wpnonce', 'key' ), 'install-sample-course' ) ) {
92 return;
93 }
94
95 if ( ! current_user_can( ADMIN_ROLE ) ) {
96 return;
97 }
98
99 ini_set( 'max_execution_time', 0 );
100
101 $data = [];
102
103 $dummy_text = LP_WP_Filesystem::instance()->file_get_contents( LP_PLUGIN_PATH . '/dummy-data/dummy-text.txt' );
104 $this->dummy_text = preg_split( '!\s!', $dummy_text );
105
106 $section_range = LP_Request::get_param( 'section-range', 0, 'int' );
107 if ( $section_range ) {
108 self::$section_range = $section_range;
109 }
110
111 $item_range = LP_Request::get_param( 'item-range', 0, 'int' );
112 if ( $item_range ) {
113 self::$item_range = $item_range;
114 }
115
116 $question_range = LP_Request::get_param( 'question-range', 0, 'int' );
117 if ( $question_range ) {
118 self::$question_range = $question_range;
119 }
120
121 $answer_range = LP_Request::get_param( 'answer-range', 0, 'int' );
122 if ( $answer_range ) {
123 self::$answer_range = $answer_range;
124 }
125
126 $data['price'] = LP_Request::get_param( CoursePostModel::META_KEY_REGULAR_PRICE, 0, 'float' );
127 $data['name'] = LP_Request::get_param( 'custom-name' );
128
129 try {
130 $course_id = $this->create_course( $data );
131
132 $this->create_sections( $course_id );
133
134 $courseModel = CourseModel::find( $course_id, true );
135 // Unset value of keys for calculate again
136 unset( $courseModel->first_item_id );
137 unset( $courseModel->total_items );
138 unset( $courseModel->sections_items );
139 unset( $courseModel->meta_data->_lp_final_quiz );
140 $courseModel->get_first_item_id();
141 $courseModel->get_total_items();
142 $courseModel->get_section_items();
143 $courseModel->get_final_quiz();
144 $courseModel->save();
145
146 $link_course = get_the_permalink( $course_id );
147 $link_course = LP_Helper::handle_lp_permalink_structure( $link_course, get_post( $course_id ) );
148 ?>
149
150 <div class="lp-install-sample__response success">
151 <?php printf( __( 'The Course "%s" has been created', 'learnpress' ), get_the_title( $course_id ) ); ?>
152 <a href="<?php echo esc_url_raw( $link_course ); ?>" target="_blank"><?php esc_html_e( 'View', 'learnpress' ); ?></a>
153 |
154 <a href="<?php echo esc_url_raw( admin_url( 'post.php?post=' . $course_id . '&action=edit' ) ); ?>" target="_blank"><?php esc_html_e( 'Edit', 'learnpress' ); ?></a>
155 </div>
156
157 <?php
158 } catch ( Exception $ex ) {
159 echo '<div class="lp-install-sample__response fail">';
160 echo wp_kses_post( $ex->getMessage() );
161 echo '</div>';
162 }
163
164 ini_set( 'max_execution_time', LearnPress::$time_limit_default_of_sever );
165
166 die();
167 }
168
169 /**
170 * Un-install
171 */
172 public function uninstall() {
173 if ( ! wp_verify_nonce( LP_Request::get_param( '_wpnonce' ), 'uninstall-sample-course' ) ) {
174 return;
175 }
176
177 $posts = $this->get_sample_posts();
178 try {
179 if ( ! $posts ) {
180 throw new Exception( esc_html__( 'No data sample.', 'learnpress' ) );
181 }
182
183 foreach ( $posts as $post ) {
184 switch ( $post->post_type ) {
185 case LP_COURSE_CPT:
186 $this->_delete_course( $post->ID );
187 break;
188 case LP_QUIZ_CPT:
189 $this->_delete_quiz( $post->ID );
190 break;
191 case LP_QUESTION_CPT:
192 $this->_delete_question( $post->ID );
193 break;
194 }
195
196 $this->_delete_post( $post->ID );
197 }
198 ?>
199
200 <div class="lp-install-sample__response success">
201 <?php esc_html_e( 'The sample data was successfully deleted!', 'learnpress' ); ?>
202 </div>
203
204 <?php
205 } catch ( Exception $ex ) {
206
207 echo '<div class="lp-install-sample__response fail">';
208 echo 'Error: ' . $ex->getMessage();
209 echo '</div>';
210 }
211
212 die();
213 }
214
215 /**
216 * Get all posts marked as "sample data"
217 *
218 * @return array|null|object
219 */
220 public function get_sample_posts() {
221 global $wpdb;
222
223 $query = $wpdb->prepare(
224 "
225 SELECT p.ID, post_type
226 FROM {$wpdb->posts} p
227 INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id AND pm.meta_key = %s AND pm.meta_value = %s
228 ",
229 '_lp_sample_data',
230 'yes'
231 );
232
233 return $wpdb->get_results( $query );
234 }
235
236 protected function _delete_course( $id ) {
237 global $wpdb;
238 $query = $wpdb->prepare(
239 "
240 SELECT section_id
241 FROM {$wpdb->learnpress_sections}
242 WHERE section_course_id = %d
243 ",
244 $id
245 );
246
247 $section_ids = $wpdb->get_col( $query );
248 if ( $section_ids ) {
249 $wpdb->query( "DELETE FROM {$wpdb->learnpress_section_items} WHERE section_id IN(" . join( ',', $section_ids ) . ')' );
250 $wpdb->query( "DELETE FROM {$wpdb->learnpress_sections} WHERE section_id IN(" . join( ',', $section_ids ) . ')' );
251 }
252 }
253
254 protected function _delete_quiz( $id ) {
255 global $wpdb;
256 $wpdb->query( "DELETE FROM {$wpdb->learnpress_quiz_questions} WHERE quiz_id = {$id}" );
257 }
258
259 protected function _delete_question( $id ) {
260 global $wpdb;
261 $wpdb->query( "DELETE FROM {$wpdb->learnpress_question_answers} WHERE question_id = {$id}" );
262 }
263
264 protected function _delete_post( $post_id ) {
265 global $wpdb;
266 $wpdb->query( "DELETE FROM {$wpdb->postmeta} WHERE post_id = $post_id" );
267 $wpdb->query( "DELETE FROM {$wpdb->posts} WHERE ID = $post_id" );
268 }
269
270 protected function _delete_user_items( $ids ) {
271 global $wpdb;
272 $format = array_fill( 0, sizeof( $ids ), '%d' );
273 $query = $wpdb->prepare(
274 "
275 DELETE
276 FROM {$wpdb->learnpress_user_items}
277 WHERE item_id IN(" . join( ',', $format ) . ')
278 ',
279 $ids
280 );
281
282 $wpdb->query( $query );
283 }
284
285 /**
286 * Generate content with 'lorem' text.
287 *
288 * @param int $min
289 * @param int $max
290 * @param int $paragraphs
291 *
292 * @return string
293 */
294 protected function generate_content( $min = 100, $max = 500, $paragraphs = 10 ) {
295 $length = rand( $min, $max );
296 $max = sizeof( $this->dummy_text ) - 1;
297 $words = array();
298
299 for ( $i = 0; $i < $length; $i++ ) {
300 $words[] = $this->dummy_text[ rand( 0, $max ) ];
301 }
302
303 $p = array();
304
305 if ( ! $paragraphs ) {
306 $paragraphs = self::$max_content_paragraph;
307 }
308
309 while ( $words && sizeof( $p ) < $paragraphs ) {
310 $len = rand( 10, 20 );
311 $cut = array_splice( $words, 0, $len );
312 $p[] = '<p>' . ucfirst( join( ' ', $cut ) ) . '</p>';
313 }
314
315 return join( '', $p );
316 }
317
318 /**
319 * Generate title with 'lorem' text.
320 *
321 * @param int $min
322 * @param int $max
323 *
324 * @return string
325 */
326 protected function generate_title( $min = 10, $max = 15 ) {
327 $length = rand( $min, $max );
328 $max = sizeof( $this->dummy_text ) - 1;
329 $words = array();
330 for ( $i = 0; $i < $length; $i++ ) {
331 $words[] = $this->dummy_text[ rand( 0, $max ) ];
332 }
333
334 return ucfirst( join( ' ', $words ) );
335 }
336
337 /**
338 * Create course.
339 *
340 * @param array $data
341 *
342 * @return int
343 * @throws Exception
344 */
345 protected function create_course( array $data ): int {
346 $title = $data['name'] ?? '';
347
348 $data_insert = array(
349 'post_title' => ! empty( $title ) ? $title : __( 'Sample course', 'learnpress' ),
350 'post_type' => LP_COURSE_CPT,
351 'post_status' => 'publish',
352 'post_content' => $this->generate_content( 25, 40, 5 ),
353 );
354
355 $courseService = CourseService::instance();
356 $coursePostModel = $courseService->create_info_main( $data_insert );
357
358 $course_id = $coursePostModel->get_id();
359
360 // Set price
361 if ( $data['price'] > 0 ) {
362 $coursePostModel->meta_data->{CoursePostModel::META_KEY_PRICE} = $data['price'];
363 $coursePostModel->meta_data->{CoursePostModel::META_KEY_REGULAR_PRICE} = $data['price'];
364 }
365
366 // Save meta data
367 $coursePostModel->meta_data->{CoursePostModel::META_KEY_DURATION} = '10 week';
368 $coursePostModel->meta_data->{CoursePostModel::META_KEY_SAMPLE_DATA} = 'yes';
369 $coursePostModel->meta_data->{CoursePostModel::META_KEY_LEVEL} = 'all';
370
371 // Requirements
372 $requirements = array();
373 for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
374 $requirements[] = $this->generate_title();
375 }
376 $coursePostModel->meta_data->{CoursePostModel::META_KEY_REQUIREMENTS} = $requirements;
377
378 // Target audiences
379 $target_audiences = array();
380 for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
381 $target_audiences[] = $this->generate_title();
382 }
383 $coursePostModel->meta_data->{CoursePostModel::META_KEY_TARGET} = $target_audiences;
384
385 // Key features
386 $key_features = array();
387 for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
388 $key_features[] = $this->generate_title();
389 }
390 $coursePostModel->meta_data->{CoursePostModel::META_KEY_FEATURES} = $key_features;
391
392 // FAQs
393 $faqs = array();
394 for ( $i = 0, $n = rand( 5, 10 ); $i <= $n; $i++ ) {
395 $faqs[] = array( $this->generate_title() . '?', $this->generate_content( 20, 30, 3 ) );
396 }
397 $coursePostModel->meta_data->{CoursePostModel::META_KEY_FAQS} = $faqs;
398
399 // Featured review
400 $coursePostModel->meta_data->{CoursePostModel::META_KEY_FEATURED_REVIEW} = $this->generate_title( 30, 40 );
401
402 $coursePostModel->save();
403
404 return $course_id;
405 }
406
407 /**
408 * Create sections.
409 *
410 * @param int $course_id
411 */
412 protected function create_sections( $course_id ) {
413 $section_length = call_user_func_array( 'rand', ( self::$section_range ) );
414
415 for ( $i = 1; $i <= $section_length; $i++ ) {
416 $section_id = $this->create_section( 'Section ' . $i, $course_id );
417
418 if ( $section_id ) {
419 $this->create_section_items( $section_id, $course_id );
420 }
421 }
422 }
423
424 /**
425 * Create section.
426 *
427 * @param string $name
428 * @param int $course_id
429 *
430 * @return int
431 */
432 protected function create_section( $name, $course_id ) {
433 static $order = 1;
434
435 global $wpdb;
436
437 $data = array(
438 'section_name' => $name,
439 'section_course_id' => $course_id,
440 'section_order' => $order,
441 'section_description' => $this->generate_title(),
442 );
443
444 $wpdb->insert(
445 $wpdb->learnpress_sections,
446 $data,
447 array( '%s', '%d', '%d', '%s' )
448 );
449
450 if ( $wpdb->insert_id ) {
451 ++$order;
452
453 return $wpdb->insert_id;
454 }
455
456 return 0;
457 }
458
459 /**
460 * Create section items.
461 *
462 * @param int $section_id
463 * @param int $course_id
464 */
465 protected function create_section_items( $section_id, $course_id ) {
466
467 static $lesson_count = 1;
468 static $quiz_count = 1;
469
470 $order = 0;
471
472 $item_length = call_user_func_array( 'rand', self::$item_range );
473
474 for ( $i = 1; $i < $item_length; $i++ ) {
475 $lesson_id = $this->create_lesson( 'Lesson ' . $lesson_count++, $section_id, $course_id, $order );
476
477 if ( $lesson_id ) {
478 ++$order;
479
480 if ( $i == 1 ) {
481 update_post_meta( $lesson_id, '_lp_preview', 'yes' );
482 }
483 }
484 }
485
486 $quiz_id = $this->create_quiz( 'Quiz ' . $quiz_count++, $section_id, $course_id, $order );
487
488 if ( $quiz_id ) {
489 ++$order;
490 }
491 }
492
493 /**
494 * Create lesson.
495 *
496 * @param string $name
497 * @param int $section_id
498 * @param int $course_id
499 *
500 * @return int|WP_Error
501 */
502 protected function create_lesson( $name, $section_id, $course_id, $order ) {
503 global $wpdb;
504
505 $data = array(
506 'post_title' => $name,
507 'post_type' => LP_LESSON_CPT,
508 'post_status' => 'publish',
509 'post_content' => $this->generate_content(),
510 );
511
512 $lesson_id = wp_insert_post( $data );
513
514 if ( $lesson_id ) {
515
516 update_post_meta( $lesson_id, '_lp_sample_data', 'yes' );
517
518 $section_data = array(
519 'section_id' => $section_id,
520 'item_id' => $lesson_id,
521 'item_type' => LP_LESSON_CPT,
522 'item_order' => absint( $order ),
523 );
524
525 $wpdb->insert(
526 $wpdb->learnpress_section_items,
527 $section_data,
528 array( '%d', '%d', '%s', '%d' )
529 );
530 }
531
532 return $lesson_id;
533 }
534
535 /**
536 * Create quiz.
537 *
538 * @param string $name
539 * @param int $section_id
540 * @param int $course_id
541 *
542 * @return int|WP_Error
543 */
544 protected function create_quiz( $name, $section_id, $course_id, $order ) {
545 global $wpdb;
546
547 $data = array(
548 'post_title' => $name,
549 'post_type' => LP_QUIZ_CPT,
550 'post_status' => 'publish',
551 'post_content' => $this->generate_content( 25, 40, 2 ),
552 );
553
554 $quiz_id = wp_insert_post( $data );
555
556 if ( $quiz_id ) {
557
558 $metas = array(
559 '_lp_preview' => 'no',
560 // '_lp_minus_points' => 0,
561 // '_lp_show_hide_question' => 'no',
562 // '_lp_review_questions' => 'yes',
563 // '_lp_show_result' => 'yes',
564 '_lp_duration' => ( rand( 1, 5 ) * 10 ) . ' ' . 'minute',
565 '_lp_passing_grade' => rand( 5, 9 ) * 10,
566 // '_lp_retake_count' => rand( 0, 10 ),
567 // '_lp_archive_history' => 'no',
568 // '_lp_show_check_answer' => '0',
569 // '_lp_show_hint' => '0',
570 '_lp_sample_data' => 'yes',
571 '_lp_negative_marking' => 'no',
572 '_lp_minus_skip_questions' => 'no',
573 '_lp_instant_check' => 'no',
574 '_lp_retake_count' => '0',
575 '_lp_pagination' => '1',
576 '_lp_review' => 'yes',
577 '_lp_show_correct_review' => 'yes',
578 );
579
580 foreach ( $metas as $key => $value ) {
581 update_post_meta( $quiz_id, $key, $value );
582 }
583
584 $section_data = array(
585 'section_id' => $section_id,
586 'item_id' => $quiz_id,
587 'item_type' => LP_QUIZ_CPT,
588 'item_order' => absint( $order ),
589 );
590
591 $wpdb->insert(
592 $wpdb->learnpress_section_items,
593 $section_data,
594 array( '%d', '%d', '%s', '%d' )
595 );
596
597 $this->create_quiz_questions( $quiz_id );
598 }
599
600 return $quiz_id;
601 }
602
603 /**
604 * Create questions of a quiz.
605 *
606 * @param int $quiz_id
607 */
608 protected function create_quiz_questions( $quiz_id ) {
609 static $question_index = 1;
610 global $wpdb;
611
612 $question_count = call_user_func_array( 'rand', self::$question_range );
613 for ( $i = 1; $i <= $question_count; $i++ ) {
614 $data = array(
615 'post_title' => 'Question ' . $question_index++,
616 'post_type' => LP_QUESTION_CPT,
617 'post_status' => 'publish',
618 'post_content' => $this->generate_content( 25, 40, 2 ),
619 );
620
621 $question_id = wp_insert_post( $data );
622
623 if ( ! $question_id ) {
624 continue;
625 }
626
627 $type = $this->get_question_type();
628
629 update_post_meta( $question_id, '_lp_type', $type );
630 update_post_meta( $question_id, '_lp_sample_data', 'yes' );
631
632 $quiz_question_data = array(
633 'quiz_id' => $quiz_id,
634 'question_id' => $question_id,
635 );
636
637 $wpdb->insert(
638 $wpdb->learnpress_quiz_questions,
639 $quiz_question_data,
640 array( '%d', '%d' )
641 );
642
643 if ( $wpdb->insert_id ) {
644 $this->create_question_answers( $question_id, $type );
645 } else {
646 error_log( 'create_quiz_questions => ', $wpdb->last_error );
647 }
648 }
649 }
650
651 /**
652 * Create answers for a question.
653 *
654 * @param int $question_id
655 * @param string $type
656 */
657 protected function create_question_answers( $question_id, $type ) {
658 global $wpdb;
659
660 $answers = $this->get_answers( $type );
661 foreach ( $answers as $order => $answer ) {
662 $data = array(
663 'question_id' => $question_id,
664 'title' => $answer['title'],
665 'value' => $answer['value'],
666 'is_true' => $answer['is_true'],
667 'order' => $order + 1,
668 );
669
670 $wpdb->insert(
671 $wpdb->learnpress_question_answers,
672 $data,
673 array( '%d', '%s', '%s', '%s', '%d' )
674 );
675 }
676 }
677
678 /**
679 * Get random answers by type of question.
680 *
681 * @param string $type
682 *
683 * @return array
684 */
685 protected function get_answers( $type ) {
686 $answers = array();
687
688 $option_count = $type === 'true_or_false' ? 2 : call_user_func_array( 'rand', self::$answer_range );
689
690 for ( $i = 1; $i <= $option_count; $i++ ) {
691 $answers[] = array(
692 'title' => $this->generate_title(),
693 'value' => learn_press_random_value(),
694 'is_true' => 'no',
695 );
696 }
697
698 // Set option is TRUE randomize
699 if ( $type !== 'multi_choice' ) {
700 $at = rand( 0, sizeof( $answers ) - 1 );
701 $answers[ $at ]['is_true'] = 'yes';
702 $answers[ $at ]['title'] = _x( '[TRUE] - ', 'install-sample-course', 'learnpress' ) . $answers[ $at ]['title'];
703 } else {
704 $has_true_option = false;
705 while ( ! $has_true_option ) {
706 foreach ( $answers as $k => $v ) {
707 $answers[ $k ]['is_true'] = rand( 0, 100 ) % 2 ? 'yes' : 'no';
708
709 if ( $answers[ $k ]['is_true'] === 'yes' ) {
710 $answers[ $k ]['title'] = _x( ' [TRUE] - ', 'install-sample-course', 'learnpress' ) . $answers[ $k ]['title'];
711 $has_true_option = true;
712 }
713 }
714 }
715 }
716
717 return $answers;
718 }
719
720 /**
721 * Get random type for a question.
722 *
723 * @return string
724 */
725 protected function get_question_type() {
726 $types = array(
727 'true_or_false',
728 'single_choice',
729 'multi_choice',
730 );
731
732 return $types[ rand( 0, sizeof( $types ) - 1 ) ];
733 }
734 }
735
736 new LP_Install_Sample_Data();
737