| @@ -23,8 +23,9 @@ | ||
| 23 | 23 | use LP_Course_Item; |
| 24 | 24 | use LP_Course_JSON_DB; |
| 25 | 25 | use LP_Course_JSON_Filter; |
| 26 | 26 | use LP_Datetime; |
| 27 | +use LP_Debug; | |
| 27 | 28 | use LP_Helper; |
| 28 | 29 | use LP_Section_Items_Filter; |
| 29 | 30 | use LP_Settings; |
| 30 | 31 | use stdClass; |
| @@ -506,29 +507,46 @@ | ||
| 506 | 507 | |
| 507 | 508 | /** |
| 508 | 509 | * Get section id of item |
| 509 | 510 | * |
| 510 | - * @param int $item_id | |
| 511 | + * A curriculum item's identity is the (item_id, item_type) pair, not the numeric | |
| 512 | + * ID alone: once items live in per-type tables a lesson and a quiz can share the | |
| 513 | + * same ID. Pass $item_type to match the composite identity. | |
| 511 | 514 | * |
| 515 | + * @param int $item_id | |
| 516 | + * @param string $item_type Optional. Curriculum item type to match as well. Empty | |
| 517 | + * keeps the legacy ID-only match for callers not yet migrated. | |
| 518 | + * | |
| 512 | 519 | * @return int |
| 513 | 520 | * @since 4.2.8 |
| 514 | - * @version 1.0.0 | |
| 521 | + * @version 1.1.0 | |
| 515 | 522 | */ |
| 516 | - public function get_section_of_item( int $item_id ): int { | |
| 517 | - $section_id = 0; | |
| 523 | + public function get_section_of_item( int $item_id, string $item_type = '' ): int { | |
| 524 | + $section_items = $this->get_section_items(); | |
| 518 | 525 | |
| 519 | - $section_items = $this->get_section_items(); | |
| 520 | 526 | foreach ( $section_items as $section ) { |
| 527 | + if ( empty( $section->items ) ) { | |
| 528 | + continue; | |
| 529 | + } | |
| 530 | + | |
| 521 | 531 | foreach ( $section->items as $item ) { |
| 522 | 532 | $item_id_check = (int) ( $item->item_id ?? $item->id ?? 0 ); |
| 523 | - if ( $item_id_check === $item_id ) { | |
| 524 | - $section_id = $section->section_id ?? $section->id ?? 0; | |
| 525 | - break; | |
| 533 | + if ( $item_id_check !== $item_id ) { | |
| 534 | + continue; | |
| 526 | 535 | } |
| 536 | + | |
| 537 | + if ( '' !== $item_type ) { | |
| 538 | + $item_type_check = (string) ( $item->item_type ?? $item->type ?? '' ); | |
| 539 | + if ( $item_type_check !== $item_type ) { | |
| 540 | + continue; | |
| 541 | + } | |
| 542 | + } | |
| 543 | + | |
| 544 | + return (int) ( $section->section_id ?? $section->id ?? 0 ); | |
| 527 | 545 | } |
| 528 | 546 | } |
| 529 | 547 | |
| 530 | - return (int) $section_id; | |
| 548 | + return 0; | |
| 531 | 549 | } |
| 532 | 550 | |
| 533 | 551 | /** |
| 534 | 552 | * Get course Evaluation type. |
| @@ -547,9 +565,9 @@ | ||
| 547 | 565 | * @param string $type |
| 548 | 566 | * |
| 549 | 567 | * @return array |
| 550 | 568 | * @since 4.3.2.6 |
| 551 | - * @version 1.0.0 | |
| 569 | + * @version 1.0.1 | |
| 552 | 570 | */ |
| 553 | 571 | public static function get_evaluation_types( string $type = '' ): array { |
| 554 | 572 | if ( has_filter( 'learnpress/course-evaluation/methods' ) ) { |
| 555 | 573 | $methods = apply_filters( 'learnpress/course-evaluation/methods', [], 0 ); |
| @@ -583,9 +601,12 @@ | ||
| 583 | 601 | |
| 584 | 602 | if ( empty( $type ) ) { |
| 585 | 603 | return $types; |
| 586 | 604 | } elseif ( empty( $types[ $type ] ) && ! empty( $methods[ $type ] ) ) { |
| 587 | - return $methods[ $type ]; | |
| 605 | + $types[ $type ] = [ | |
| 606 | + 'label' => strip_tags( $methods[ $type ] ), | |
| 607 | + 'tip' => strip_tags( $methods[ $type ] ), | |
| 608 | + ]; | |
| 588 | 609 | } |
| 589 | 610 | |
| 590 | 611 | return $types[ $type ] ?? []; |
| 591 | 612 | } |
| @@ -766,9 +787,9 @@ | ||
| 766 | 787 | return $section1->section_order - $section2->section_order; |
| 767 | 788 | } |
| 768 | 789 | ); |
| 769 | 790 | } catch ( Throwable $e ) { |
| 770 | - error_log( $e->getMessage() ); | |
| 791 | + LP_Debug::error_log( $e ); | |
| 771 | 792 | } |
| 772 | 793 | |
| 773 | 794 | return $sections_items; |
| 774 | 795 | } |
| @@ -851,9 +872,9 @@ | ||
| 851 | 872 | $coursePost = new CoursePostModel( $this ); |
| 852 | 873 | $value = $coursePost->get_meta_value_by_key( $key, $default_value, $single ); |
| 853 | 874 | } |
| 854 | 875 | |
| 855 | - $value = maybe_unserialize( $value ); | |
| 876 | + $value = maybe_unserialize( $value ); | |
| 856 | 877 | $this->meta_data->{$key} = $value; |
| 857 | 878 | |
| 858 | 879 | return $value; |
| 859 | 880 | } |
| @@ -966,9 +987,9 @@ | ||
| 966 | 987 | $lp_course_db = LP_Course_DB::getInstance(); |
| 967 | 988 | $total = $lp_course_db->get_total_user_enrolled_or_purchased( $this->get_id() ); |
| 968 | 989 | $lp_course_cache->set_total_students_enrolled_or_purchased( $this->get_id(), $total ); |
| 969 | 990 | } catch ( Throwable $e ) { |
| 970 | - error_log( $e->getMessage() ); | |
| 991 | + LP_Debug::error_log( $e ); | |
| 971 | 992 | } |
| 972 | 993 | |
| 973 | 994 | return $total; |
| 974 | 995 | } |
| @@ -1255,16 +1276,27 @@ | ||
| 1255 | 1276 | |
| 1256 | 1277 | /** |
| 1257 | 1278 | * Get item model assigned to this course |
| 1258 | 1279 | * |
| 1280 | + * @param int $item_id | |
| 1281 | + * @param string $item_type | |
| 1282 | + * @param bool $check_assign | default true check assign item to course | |
| 1283 | + * | |
| 1259 | 1284 | * @return mixed|false|null|WP_Post|PostModel |
| 1260 | 1285 | * @since v4.2.7.6 |
| 1261 | - * @version 1.0.1 | |
| 1286 | + * @version 1.0.3 | |
| 1262 | 1287 | */ |
| 1263 | - public function get_item_model( int $item_id, string $item_type ) { | |
| 1288 | + public function get_item_model( int $item_id, string $item_type, bool $check_assign = true ) { | |
| 1264 | 1289 | try { |
| 1265 | 1290 | $item = false; |
| 1266 | 1291 | |
| 1292 | + // Find item has in section. Match the composite (item_id, item_type) identity, | |
| 1293 | + // so a quiz ID can never resolve through a lesson request and vice versa. | |
| 1294 | + $section_id = $this->get_section_of_item( $item_id, $item_type ); | |
| 1295 | + if ( $check_assign && ! $section_id ) { | |
| 1296 | + return $item; | |
| 1297 | + } | |
| 1298 | + | |
| 1267 | 1299 | switch ( $item_type ) { |
| 1268 | 1300 | case LP_LESSON_CPT: |
| 1269 | 1301 | $item = LessonPostModel::find( $item_id, true ); |
| 1270 | 1302 | break; |
| @@ -1285,9 +1317,9 @@ | ||
| 1285 | 1317 | $filter->post_type = $item_type; |
| 1286 | 1318 | $item = PostModel::get_item_model_from_db( $filter ); |
| 1287 | 1319 | } |
| 1288 | 1320 | } catch ( Exception $e ) { |
| 1289 | - error_log( __METHOD__ . ': ' . $e->getMessage() ); | |
| 1321 | + LP_Debug::error_log( $e ); | |
| 1290 | 1322 | } |
| 1291 | 1323 | |
| 1292 | 1324 | return $item; |
| 1293 | 1325 | } |
| @@ -1317,9 +1349,9 @@ | ||
| 1317 | 1349 | $course_model->post_content = $course_rs->post_content; |
| 1318 | 1350 | $course_model->get_author_model(); |
| 1319 | 1351 | } |
| 1320 | 1352 | } catch ( Throwable $e ) { |
| 1321 | - error_log( __METHOD__ . ': ' . $e->getMessage() ); | |
| 1353 | + LP_Debug::error_log( $e ); | |
| 1322 | 1354 | } |
| 1323 | 1355 | |
| 1324 | 1356 | return $course_model; |
| 1325 | 1357 | } |