PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.1.7
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.1.7
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 / course / class-lp-course.php

class-lp-course.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.1.7, at inc/course/class-lp-course.php

876 lines 24.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Class LP_Course.
4 *
5 * @author ThimPress
6 * @package LearnPress/Classes
7 * @version 4.0.1
8 */
9
10 defined( 'ABSPATH' ) || exit();
11
12 if ( ! class_exists( 'LP_Course' ) ) {
13
14 /**
15 * Class LP_Course
16 */
17 class LP_Course extends LP_Abstract_Course {
18 protected $key_info_extra_fast_query = '_lp_info_extra_fast_query';
19
20 /**
21 * LP_Course constructor.
22 *
23 * @param mixed $course
24 */
25 public function __construct( $course ) {
26 parent::__construct( $course );
27 }
28
29 /**
30 * Debug log.
31 *
32 * @param $data
33 *
34 * @return array
35 * @editor tungnx
36 * @modify 4.1.5 - comment - not use
37 */
38 /*public static function log( $data ) {
39 return $data;
40 }*/
41
42 /**
43 * Get default course meta.
44 *
45 * @return mixed
46 * @since 3.0.0
47 */
48 public static function get_default_meta() {
49 $meta = array(
50 'duration' => '10 weeks',
51 'max_students' => 1000,
52 'students' => 0,
53 'retake_count' => 0,
54 'featured' => 'no',
55 //'block_lesson_content' => 'no',
56 'external_link_buy_course' => '',
57 'course_result' => 'evaluate_lesson',
58 'passing_condition' => 80,
59 'price' => '',
60 'sale_price' => '',
61 'sale_start' => '',
62 'sale_end' => '',
63 'required_enroll' => 'yes',
64 'course_author' => learn_press_get_current_user_id(),
65 );
66
67 return apply_filters( 'learn-press/course/default-meta', $meta );
68 }
69
70 /**
71 * Get LP Course.
72 *
73 * @param int $course_id
74 *
75 * @return mixed|bool|LP_Course
76 */
77 public static function get_course( int $course_id = 0 ) {
78 if ( isset( LP_Global::$courses[ $course_id ] ) ) {
79 return LP_Global::$courses[ $course_id ];
80 }
81
82 $the_course = self::get_course_object( $course_id );
83
84 if ( ! $the_course ) {
85 return false;
86 }
87
88 $key_args = wp_parse_args(
89 array(
90 'id' => $the_course->ID,
91 'type' => $the_course->post_type,
92 )
93 );
94
95 $key = LP_Helper::array_to_md5( $key_args );
96
97 if ( empty( LP_Global::$courses[ $key ] ) ) {
98 $class_name = self::get_course_class( $the_course );
99 if ( is_string( $class_name ) && class_exists( $class_name ) ) {
100 $course = new $class_name( $the_course->ID );
101 } elseif ( $class_name instanceof LP_Abstract_Course ) {
102 $course = $class_name;
103 } else {
104 $course = new self( $the_course->ID );
105 }
106 LP_Global::$courses[ $key ] = $course;
107 } else {
108 $course = LP_Global::$courses[ $key ];
109 }
110
111 /**
112 * Force to reload course data into cache if it is not
113 * loaded or has been deleted for some reasons.
114 */
115 $course->load();
116
117 return $course;
118 }
119
120 /**
121 * @param string $course_type
122 *
123 * @return string|false
124 */
125 private static function get_class_name_from_course_type( $course_type ) {
126 return LP_COURSE_CPT === $course_type ? __CLASS__ : 'LP_Course_' . implode(
127 '_',
128 array_map( 'ucfirst', explode( '-', $course_type ) )
129 );
130 }
131
132 /**
133 * Get the course class name
134 *
135 * @param WP_Post $the_course
136 * @param array $args (default: array())
137 *
138 * @return string
139 */
140 private static function get_course_class( $the_course, $args = array() ) {
141 $course_id = absint( $the_course->ID );
142 $type = $the_course->post_type;
143
144 $class_name = self::get_class_name_from_course_type( $type );
145
146 // Filter class name so that the class can be overridden if extended.
147 return apply_filters( 'learn-press/course/object-class', $class_name, $type, $course_id );
148 }
149
150 /**
151 * Get the course object
152 *
153 * @param mixed $the_course
154 *
155 * @return WP_Post|bool false on failure
156 * @uses WP_Post
157 */
158 private static function get_course_object( $the_course ) {
159 $the_course_passed = $the_course;
160 if ( false === $the_course ) {
161 $the_course = get_post_type() === LP_COURSE_CPT ? $GLOBALS['post'] : false;
162 } elseif ( is_numeric( $the_course ) ) {
163 $the_course = get_post( $the_course );
164 } elseif ( $the_course instanceof LP_Abstract_Course ) {
165 $the_course = get_post( $the_course->get_id() );
166 } elseif ( ! ( $the_course instanceof WP_Post ) ) {
167 $the_course = false;
168 }
169
170 if ( $the_course && $the_course->post_type !== LP_COURSE_CPT ) {
171 $the_course = false;
172 }
173
174 return apply_filters( 'learn-press/course/post-object', $the_course, $the_course_passed );
175 }
176
177 /**
178 * Check time remaining course when enable duration expire
179 * Value: -1 is no limit (default)
180 * Value: 0 is block
181 * Administrator || (is instructor && is author course) will be not block.
182 *
183 * @return int second
184 * @since 4.0.0
185 * @author tungnx
186 * @version 1.0.1
187 */
188 public function timestamp_remaining_duration(): int {
189 $timestamp_remaining = - 1;
190 $user = learn_press_get_user( get_current_user_id() );
191
192 if ( current_user_can( 'administrator' ) ||
193 ( current_user_can( LP_TEACHER_ROLE ) && $this->get_author()->get_id() === $user->get_id() ) ) {
194 return $timestamp_remaining;
195 }
196
197 if ( 0 === absint( $this->get_data( 'duration' ) ) ) {
198 return $timestamp_remaining;
199 }
200
201 if ( 'yes' !== $this->get_data( 'block_course_duration_expire' ) ) {
202 return $timestamp_remaining;
203 }
204
205 if ( $user instanceof LP_User_Guest ) {
206 return $timestamp_remaining;
207 }
208
209 $course_item_data = $user->get_course_data( $this->get_id() );
210
211 if ( ! $course_item_data ) {
212 return $timestamp_remaining;
213 }
214
215 $course_start_time = $course_item_data->get_start_time()->get_raw_date();
216 $duration = $this->get_data( 'duration' );
217 $timestamp_expire = strtotime( $course_start_time . ' +' . $duration );
218 $timestamp_current = strtotime( current_time( 'mysql' ) );
219 $timestamp_remaining = $timestamp_expire - $timestamp_current;
220
221 if ( $timestamp_remaining < 0 ) {
222 $timestamp_remaining = 0;
223 }
224
225 return apply_filters( 'learnpress/course/block_duration_expire/timestamp_remaining', $timestamp_remaining );
226 }
227
228 /**
229 * Get option enable block course when finish course
230 *
231 * @return bool
232 */
233 public function enable_block_item_when_finish(): bool {
234 return 'yes' === $this->get_data( 'block_course_finished' );
235 }
236
237 public function allow_repurchase() : bool {
238 return 'yes' === $this->get_data( 'allow_repurchase' );
239 }
240
241 public function allow_repurchase_course_option() : string {
242 return $this->get_data( 'allow_repurchase_course_option', 'reset' );
243 }
244
245 /**
246 * Get first item of course
247 *
248 * @author tungnx
249 * @since 4.0.0
250 * @modify 4.1.3
251 * @version 1.0.1
252 * @return int
253 */
254 public function get_first_item_id(): int {
255 $course_id = $this->get_id();
256
257 try {
258 // Get cache
259 $lp_course_cache = LP_Course_Cache::instance();
260 $key_cache = "$course_id/first_item_id";
261 $first_item_id = $lp_course_cache->get_cache( $key_cache );
262
263 if ( ! $first_item_id ) {
264 $extra_info = $this->get_info_extra_for_fast_query();
265
266 if ( ! $extra_info->first_item_id ) {
267 $first_item_id = LP_Course_DB::getInstance()->get_first_item_id( $course_id );
268 $extra_info->first_item_id = $first_item_id;
269
270 // Save post meta
271 $this->set_info_extra_for_fast_query( $extra_info );
272 } else {
273 $first_item_id = $extra_info->first_item_id;
274 }
275
276 $lp_course_cache->set_cache( $key_cache, $first_item_id );
277 }
278 } catch ( Throwable $e ) {
279 $first_item_id = 0;
280 }
281
282 return $first_item_id;
283 }
284
285 /**
286 * Get redirect url after enroll course
287 *
288 * @author tungnx
289 * @version 1.0.0
290 * @since 4.0.0
291 * @return false|string|WP_Error
292 */
293 public function get_redirect_url_after_enroll() {
294 $first_item_id = $this->get_first_item_id();
295 $redirect = $first_item_id ? $this->get_item_link( $first_item_id ) : get_the_permalink( $this->get_id() );
296
297 return apply_filters( 'learnpress/rest-api/enroll-course/redirect', $redirect );
298 }
299
300 /**
301 * Get info extra on post meta to query fast
302 *
303 * @since 4.1.3
304 * @author tungnx
305 * @version 1.0.0
306 * @return LP_Course_Extra_Info_Fast_Query_Model
307 */
308 public function get_info_extra_for_fast_query(): LP_Course_Extra_Info_Fast_Query_Model {
309 $extra_info = new LP_Course_Extra_Info_Fast_Query_Model();
310
311 try {
312 $extra_info_str = get_post_meta( $this->get_id(), $this->key_info_extra_fast_query, true );
313
314 if ( $extra_info_str ) {
315 $extra_info_stdclass = json_decode( $extra_info_str );
316
317 if ( JSON_ERROR_NONE !== json_last_error() ) {
318 throw new Exception( 'Error json decode on ' . __METHOD__ );
319 }
320
321 $extra_info = $extra_info->map_stdclass( $extra_info_stdclass );
322 }
323 } catch ( Throwable $e ) {
324 error_log( $e->getMessage() );
325 }
326
327 return $extra_info;
328 }
329
330 /**
331 * Set extra info for query fast on post meta
332 *
333 * @since 4.1.3
334 * @author tungnx
335 * @version 1.0.0
336 * @param LP_Course_Extra_Info_Fast_Query_Model $data_object
337 */
338 public function set_info_extra_for_fast_query( LP_Course_Extra_Info_Fast_Query_Model $data_object ) {
339 try {
340 $extra_info_json = json_encode( $data_object, JSON_UNESCAPED_UNICODE );
341
342 if ( JSON_ERROR_NONE !== json_last_error() ) {
343 throw new Exception( 'Error encode on ' . __METHOD__ );
344 }
345
346 update_post_meta( $this->get_id(), $this->key_info_extra_fast_query, $extra_info_json );
347 } catch ( Throwable $e ) {
348 error_log( $e->getMessage() );
349 }
350 }
351
352 /**
353 * Get info total items of Course
354 *
355 * @param string $type
356 * @param bool $include_preview
357 * @author tungnx
358 * @since 4.1.4.1
359 * @version 1.0.0
360 * @return int
361 */
362 public function count_items( string $type = '', bool $include_preview = true ): int {
363 $course_id = $this->get_id();
364
365 // Get cache
366 $lp_course_cache = LP_Course_Cache::instance();
367 $key_cache = "$course_id/total_items";
368 $total_items = $lp_course_cache->get_cache( $key_cache );
369 $count_items = 0;
370
371 if ( ! $total_items ) {
372 $extra_info = $this->get_info_extra_for_fast_query();
373
374 if ( ! $extra_info->total_items ) {
375 $total_items = LP_Course_DB::getInstance()->get_total_items( $course_id );
376 $extra_info->total_items = $total_items;
377
378 // Save post meta
379 $this->set_info_extra_for_fast_query( $extra_info );
380 } else {
381 $total_items = $extra_info->total_items;
382 }
383
384 $lp_course_cache->set_cache( $key_cache, $total_items );
385 }
386
387 if ( ! empty( $total_items ) ) {
388 if ( ! empty( $type ) ) {
389 if ( isset( $total_items->{$type} ) ) {
390 $count_items = $total_items->{$type};
391 }
392 } else {
393 $count_items = $total_items->count_items;
394 }
395 }
396
397 return apply_filters( 'learn-press/course/count-items', intval( $count_items ), $course_id );
398 }
399
400 /**
401 * Delete relate data when delete course
402 *
403 * @since 4.1.4.1
404 * @author tungnx
405 * @version 1.0.0
406 */
407 public function delete_relate_data_when_delete_course() {
408 $lp_section_db = LP_Section_DB::getInstance();
409 $lp_user_items_db = LP_User_Items_DB::getInstance();
410
411 try {
412 // Check valid user
413 if ( ! current_user_can( 'administrator' ) && $this->get_author( 'id' ) !== get_current_user_id() ) {
414 return;
415 }
416
417 $section_ids = $lp_section_db->get_section_ids_by_course( $this->get_id() );
418
419 $filter = new LP_Section_Filter();
420 $filter->section_ids = $section_ids;
421 $filter->author_id_course = $this->get_author( 'id' );
422
423 // Delete section
424 $lp_section_db->delete_section( $filter );
425 // Delete section items
426 $lp_section_db->delete_section_items( $filter );
427
428 $filter_user_items = new LP_User_Items_Filter();
429 $filter_user_items->item_id = $this->get_id();
430 $user_course_ids = $lp_user_items_db->get_user_items_by_course( $filter_user_items );
431
432 $this->delete_user_item_and_result( $user_course_ids );
433 } catch ( Throwable $e ) {
434 error_log( __FUNCTION__ . ':' . $e->getMessage() );
435 }
436 }
437
438 /**
439 * Delete user_items, user_itemmeta, user_item_results
440 * WHERE IN user_item_ids
441 *
442 * @param array $user_course_ids
443 */
444 public function delete_user_item_and_result( array $user_course_ids ) {
445 $lp_user_items_db = LP_User_Items_DB::getInstance();
446 $lp_user_item_results = LP_User_Items_Result_DB::instance();
447
448 try {
449 if ( empty( $user_course_ids ) ) {
450 return;
451 }
452
453 // Get user_item_ids has parent in $user_course_ids
454 $filter = new LP_User_Items_Filter();
455 $filter->user_item_ids = $user_course_ids;
456 $user_item_ids = $lp_user_items_db->get_item_ids_of_user_course( $filter );
457
458 $user_item_ids_concat = array_merge( $user_course_ids, $user_item_ids );
459
460 // Delete on tb lp_user_items
461 $filter_delete = new LP_User_Items_Filter();
462 $filter_delete->user_item_ids = $user_item_ids_concat;
463 $lp_user_items_db->remove_user_item_ids( $filter_delete );
464
465 // Delete user_itemmeta
466 $lp_user_items_db->remove_user_itemmeta( $filter_delete );
467
468 // Delete user_item_results
469 $lp_user_item_results->remove_user_item_results( $filter_delete );
470 } catch ( Throwable $e ) {
471 error_log( __FUNCTION__ . ':' . $e->getMessage() );
472 }
473 }
474
475 /**
476 * Get list course
477 * Order By: price, title, rating, date ...
478 * Order: ASC, DES
479 *
480 * @param LP_Course_Filter $filter
481 * @param int $total_rows
482 *
483 * @return array|null|string|int
484 * @author tungnx
485 * @version 1.0.0
486 * @sicne 4.1.5
487 */
488 public static function get_courses( LP_Course_Filter $filter, int &$total_rows = 0 ) {
489 $lp_course_db = LP_Course_DB::getInstance();
490
491 try {
492 $key_cache = md5( json_encode( $filter ) );
493 $key_cache_total_rows = md5( json_encode( $filter ) . 'total_rows' );
494 $courses_cache = LP_Courses_Cache::instance()->get_cache( $key_cache );
495
496 if ( false !== $courses_cache ) {
497 $total_rows = LP_Courses_Cache::instance()->get_cache( $key_cache_total_rows );
498 return $courses_cache;
499 }
500
501 // Sort by
502 $filter->sort_by = (array) $filter->sort_by;
503 foreach ( $filter->sort_by as $sort_by ) {
504 $filter_tmp = clone $filter;
505 $filter_tmp->only_fields = array( 'ID' );
506 $filter_tmp->return_string_query = true;
507
508 switch ( $sort_by ) {
509 case 'on_sale':
510 $filter_tmp = $lp_course_db->get_courses_sort_by_sale( $filter_tmp );
511 break;
512 case 'on_feature':
513 $filter_tmp = $lp_course_db->get_courses_sort_by_feature( $filter_tmp );
514 break;
515 default:
516 $filter_tmp = apply_filters( 'lp/courses/filter/sort_by/' . $sort_by, $filter_tmp );
517 break;
518 }
519
520 $query_courses_str = $lp_course_db->get_courses( $filter_tmp );
521
522 $filter->where[] = "AND ID IN ({$query_courses_str})";
523 }
524
525 // Order by
526 switch ( $filter->order_by ) {
527 case 'price':
528 case 'price_low':
529 if ( 'price_low' === $filter->order_by ) {
530 $filter->order = 'ASC';
531 } else {
532 $filter->order = 'DESC';
533 }
534
535 $filter = $lp_course_db->get_courses_order_by_price( $filter );
536 break;
537 case 'popular':
538 $filter = $lp_course_db->get_courses_order_by_popular( $filter );
539 break;
540 default:
541 $filter = apply_filters( 'lp/courses/filter/order_by/' . $filter->order_by, $filter );
542 break;
543 }
544
545 // Query get results
546 $filter = apply_filters( 'lp/courses/filter', $filter );
547 $courses = LP_Course_DB::getInstance()->get_courses( $filter, $total_rows );
548
549 LP_Courses_Cache::instance()->set_cache( $key_cache, $courses );
550 LP_Courses_Cache::instance()->set_cache( $key_cache_total_rows, $total_rows );
551
552 /**
553 * Save key cache to array to clear
554 * @see LP_Background_Single_Course::save_post() - clear cache when save post
555 */
556 LP_Courses_Cache::instance()->save_cache_keys( $key_cache );
557 LP_Courses_Cache::instance()->save_cache_keys( $key_cache_total_rows );
558 } catch ( Throwable $e ) {
559 $courses = [];
560 error_log( __FUNCTION__ . ': ' . $e->getMessage() );
561 }
562
563 return $courses;
564 }
565
566 /**
567 * Get full sections, items of course via Cache, extra info (if it has)
568 *
569 * @return array
570 * @since 4.1.6.9
571 * @version 1.0.0
572 * @author tungnx
573 */
574 public function get_full_sections_and_items_course(): array {
575 $sections_items = [];
576 $course_id = $this->get_id();
577
578 try {
579 // Get cache
580 $lp_course_cache = LP_Course_Cache::instance();
581 $key_cache = "$course_id/sections_items";
582 $sections_items = $lp_course_cache->get_cache( $key_cache );
583
584 if ( ! $sections_items ) {
585 $extra_info = $this->get_info_extra_for_fast_query();
586
587 if ( empty( $extra_info->sections_items ) ) {
588 $sections_items = $this->get_sections_and_items_course_from_db_and_sort();
589 $extra_info->sections_items = $sections_items;
590
591 // Save post meta
592 $this->set_info_extra_for_fast_query( $extra_info );
593 } else {
594 $sections_items = $extra_info->sections_items;
595 }
596
597 $lp_course_cache->set_cache( $key_cache, $sections_items );
598 }
599 } catch ( Throwable $e ) {
600 if ( LP_Debug::is_debug() ) {
601 error_log( $e->getMessage() );
602 }
603 }
604
605 return $sections_items;
606 }
607
608 /**
609 * Get all sections and items from database, then handle sort
610 * Only call when data change or not set
611 *
612 * @return array
613 * @since 4.1.6.9
614 * @version 1.0.0
615 * @author tungnx
616 */
617 public function get_sections_and_items_course_from_db_and_sort(): array {
618 $sections_items = [];
619 $course_id = $this->get_id();
620 $lp_course_db = LP_Course_DB::getInstance();
621 $lp_course_cache = LP_Course_Cache::instance();
622 $key_cache = "$course_id/sections_items";
623
624 try {
625 $sections_results = $lp_course_db->get_sections( $course_id );
626 $sections_items_results = $lp_course_db->get_full_sections_and_items_course( $course_id );
627 $count_items = count( $sections_items_results );
628 $index_items_last = $count_items - 1;
629 $section_current = 0;
630
631 foreach ( $sections_items_results as $index => $sections_item ) {
632 $section_new = $sections_item->section_id;
633 $section_order = $sections_item->section_order;
634 $item = new stdClass();
635 $item->id = $sections_item->item_id;
636 $item->order = $sections_item->item_order;
637 $item->type = $sections_item->item_type;
638
639 if ( $section_new != $section_current ) {
640 $sections_items[ $section_new ] = new stdClass();
641 $sections_items[ $section_new ]->id = $section_new;
642 $sections_items[ $section_new ]->order = $section_order;
643 $sections_items[ $section_new ]->title = html_entity_decode( $sections_item->section_name );
644 $sections_items[ $section_new ]->description = html_entity_decode( $sections_item->section_description );
645 $sections_items[ $section_new ]->items = [];
646
647 // Sort item by item_order
648 if ( $section_current != 0 ) {
649 usort(
650 $sections_items[ $section_current ]->items,
651 function ( $item1, $item2 ) {
652 return $item1->order - $item2->order;
653 }
654 );
655 }
656
657 $section_current = $section_new;
658 }
659
660 $sections_items[ $section_new ]->items[ $item->id ] = $item;
661
662 if ( $index_items_last === $index ) {
663 usort(
664 $sections_items[ $section_current ]->items,
665 function ( $item1, $item2 ) {
666 return $item1->order - $item2->order;
667 }
668 );
669 }
670 }
671
672 // Check case if section empty items
673 foreach ( $sections_results as $section ) {
674 $section_id = $section->section_id;
675 if ( isset( $sections_items[ $section_id ] ) ) {
676 continue;
677 }
678
679 $section_obj = new stdClass();
680 $section_obj->id = $section_id;
681 $section_obj->order = $section->section_order;
682 $section_obj->title = html_entity_decode( $section->section_name );
683 $section_obj->description = html_entity_decode( $section->section_description );
684 $section_obj->items = [];
685 $sections_items[ $section_id ] = $section_obj;
686 }
687
688 // Sort section by section_order
689 usort(
690 $sections_items,
691 function ( $section1, $section2 ) {
692 return $section1->order - $section2->order;
693 }
694 );
695
696 $lp_course_cache->set_cache( $key_cache, $sections_items );
697 } catch ( Throwable $e ) {
698 if ( LP_Debug::is_debug() ) {
699 error_log( $e->getMessage() );
700 }
701 }
702
703 return $sections_items;
704 }
705
706 /**
707 * Get sections of course.
708 *
709 * @param string $return - Optional.
710 * @param int $section_id - Optional.
711 *
712 * @return array|bool|LP_Course_Section[]|LP_Course_Section
713 * @version 4.0.0
714 */
715 public function get_sections( $return = 'object', $section_id = 0 ) {
716 // $this->load_curriculum();
717 // $sections = LP_Course_Utils::get_cached_db_sections( $this->get_id() );
718
719 $sections_items = $this->get_full_sections_and_items_course();
720
721 /*if ( false === $sections ) {
722 return false;
723 }*/
724
725 //$position = 0;
726 $sections = array();
727 foreach ( $sections_items as $k => $section_items ) {
728 $position = $k + 1;
729 $section_items_tmp = [
730 'section_id' => $section_items->id,
731 'section_name' => $section_items->title,
732 'section_course_id' => $this->get_id(),
733 'section_order' => $section_items->order,
734 'section_description' => $section_items->description,
735 'items' => $section_items->items,
736 ];
737 $sid = $section_items->id;
738 $section = new LP_Course_Section( $section_items_tmp );
739 $section->set_position( $position );
740 $sections[ $sid ] = $section;
741 }
742
743 if ( $section_id ) {
744 $sections = $sections[ $section_id ] ?? [];
745 }
746
747 return apply_filters( 'learn-press/course-sections', $sections, $this->get_id(), $return, $section_id );
748 }
749
750 /**
751 * Get sections arr
752 *
753 * @param int $section_id
754 *
755 * @return array
756 * @version 1.0.0
757 * @sicne 4.1.7
758 */
759 public function get_sections_data_arr( int $section_id = 0 ): array {
760 $sections_items = $this->get_full_sections_and_items_course();
761 $sections = array();
762
763 foreach ( $sections_items as $section_items ) {
764 $section = [
765 'section_id' => $section_items->id,
766 'section_name' => $section_items->title,
767 'section_course_id' => $this->get_id(),
768 'section_order' => $section_items->order,
769 'section_description' => $section_items->description,
770 'items' => $section_items->items,
771 ];
772
773 if ( $section_id && $section_id == $section['section_id'] ) {
774 $sections = $section;
775 break;
776 }
777
778 $sections[] = $section;
779 }
780
781 return $sections;
782 }
783
784 /**
785 * Get raw data curriculum.
786 *
787 * @return array
788 * @since 3.0.0
789 * @editor tungnx
790 * @version 1.0.1
791 */
792 public function get_curriculum_raw(): array {
793 $sections_data = array();
794
795 $sections_items = $this->get_full_sections_and_items_course();
796 foreach ( $sections_items as $section_items ) {
797 $section_items_arr = (array) $section_items;
798 $section_items_arr['course_id'] = $this->get_id();
799 $section_items_arr['items'] = [];
800
801 foreach ( $section_items->items as $item ) {
802 $itemObject = $this->get_item( $item->id );
803
804 if ( ! $itemObject instanceof LP_Course_Item ) {
805 continue;
806 }
807
808 $item_arr = (array) $item;
809 $item_arr['title'] = html_entity_decode( $itemObject->get_title() );
810 $item_arr['preview'] = $itemObject->is_preview();
811 $section_items_arr['items'][] = apply_filters( 'learn-press/item/to_array', $item_arr );
812 }
813
814 $sections_data[] = $section_items_arr;
815 }
816
817 return $sections_data;
818 }
819
820 /**
821 * Get all curriculum of this course.
822 *
823 * @param int $section_id
824 * @param bool $force
825 *
826 * @return bool|LP_Course_Section[]
827 */
828 public function get_curriculum( $section_id = 0, $force = false ) {
829 return $this->get_sections( 'object', $section_id );
830 }
831
832 /**
833 * Return list of item's ids in course's curriculum.
834 *
835 * @param string|array $type
836 *
837 * @return array
838 * @since 3.0.0
839 * @version 3.0.2
840 */
841 public function get_items( $type = '' ) {
842 //$this->load();
843
844 $sections_items = $this->get_full_sections_and_items_course();
845
846 $items = array();
847
848 foreach ( $sections_items as $section_items ) {
849 foreach ( $section_items->items as $item ) {
850 if ( ! empty( $type ) ) {
851 if ( $type === $item->type ) {
852 $items[] = $item->id;
853 }
854 } else {
855 $items[] = $item->id;
856 }
857 }
858 }
859
860 return $items;
861 }
862
863 /**
864 * Get all items in a course.
865 *
866 * @param string $type . Type of items, eg: lp_lesson, lp_quiz...
867 *
868 * @return array
869 * @deprecated
870 */
871 public function get_curriculum_items( $type = '' ) {
872 return $this->get_items( $type );
873 }
874 }
875 }
876