Total Complexity | 248 |
Total Lines | 2767 |
Duplicated Lines | 0 % |
Changes | 2 | ||
Bugs | 0 | Features | 0 |
Complex classes like Event often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Event, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
14 | class Event |
||
15 | { |
||
16 | /** |
||
17 | * @author Sebastien Piraux <[email protected]> |
||
18 | * @desc Record information for open event (when homepage is opened) |
||
19 | */ |
||
20 | public static function open() |
||
53 | } |
||
54 | |||
55 | /** |
||
56 | * @author Sebastien Piraux <[email protected]> old code |
||
57 | * @author Julio Montoya |
||
58 | * |
||
59 | * @param int $userId |
||
60 | * |
||
61 | * @return bool |
||
62 | * @desc Record information for login event when an user identifies himself with username & password |
||
63 | */ |
||
64 | public static function eventLogin($userId) |
||
65 | { |
||
66 | $userInfo = api_get_user_info($userId); |
||
67 | $userId = (int) $userId; |
||
68 | |||
69 | if (empty($userInfo)) { |
||
70 | return false; |
||
71 | } |
||
72 | |||
73 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); |
||
74 | $reallyNow = api_get_utc_datetime(); |
||
75 | $userIp = Database::escape_string(api_get_real_ip()); |
||
76 | |||
77 | $sql = "INSERT INTO $table (login_user_id, user_ip, login_date, logout_date) VALUES |
||
78 | ($userId, |
||
79 | '$userIp', |
||
80 | '$reallyNow', |
||
81 | '$reallyNow' |
||
82 | )"; |
||
83 | Database::query($sql); |
||
84 | |||
85 | // Auto subscribe |
||
86 | $status = 'student'; |
||
87 | if ($userInfo['status'] == SESSIONADMIN) { |
||
88 | $status = 'sessionadmin'; |
||
89 | } |
||
90 | if ($userInfo['status'] == COURSEMANAGER) { |
||
91 | $status = 'teacher'; |
||
92 | } |
||
93 | if ($userInfo['status'] == DRH) { |
||
94 | $status = 'DRH'; |
||
95 | } |
||
96 | |||
97 | $autoSubscribe = api_get_setting($status.'_autosubscribe'); |
||
98 | if ($autoSubscribe) { |
||
99 | $autoSubscribe = explode('|', $autoSubscribe); |
||
100 | foreach ($autoSubscribe as $code) { |
||
101 | if (CourseManager::course_exists($code)) { |
||
102 | CourseManager::subscribeUser($userId, $code); |
||
103 | } |
||
104 | } |
||
105 | } |
||
106 | |||
107 | return true; |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | * @param int $sessionId |
||
112 | * |
||
113 | * @return bool |
||
114 | */ |
||
115 | public static function isSessionLogNeedToBeSave($sessionId) |
||
132 | } |
||
133 | |||
134 | /** |
||
135 | * @author Sebastien Piraux <[email protected]> |
||
136 | * @desc Record information for access event for courses |
||
137 | * |
||
138 | * @return bool |
||
139 | */ |
||
140 | public static function accessCourse() |
||
186 | } |
||
187 | |||
188 | /** |
||
189 | * @param string $tool name of the tool |
||
190 | * |
||
191 | * @author Sebastien Piraux <[email protected]> |
||
192 | * @desc Record information for access event for tools |
||
193 | * |
||
194 | * $tool can take this values : |
||
195 | * Links, Calendar, Document, Announcements, |
||
196 | * Group, Video, Works, Users, Exercises, Course Desc |
||
197 | * ... |
||
198 | * Values can be added if new modules are created (15char max) |
||
199 | * I encourage to use $nameTool as $tool when calling this function |
||
200 | * |
||
201 | * Functionality for "what's new" notification is added by Toon Van Hoecke |
||
202 | * |
||
203 | * @return bool |
||
204 | */ |
||
205 | public static function event_access_tool($tool) |
||
281 | } |
||
282 | |||
283 | /** |
||
284 | * Record information for download event (when an user click to d/l a |
||
285 | * document) it will be used in a redirection page. |
||
286 | * |
||
287 | * @param string $documentUrl |
||
288 | * |
||
289 | * @return int |
||
290 | * |
||
291 | * @author Sebastien Piraux <[email protected]> |
||
292 | * @author Evie Embrechts (bug fixed: The user id is put in single quotes) |
||
293 | */ |
||
294 | public static function event_download($documentUrl) |
||
295 | { |
||
296 | if (Session::read('login_as')) { |
||
297 | return false; |
||
298 | } |
||
299 | |||
300 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DOWNLOADS); |
||
301 | $documentUrl = Database::escape_string($documentUrl); |
||
302 | |||
303 | $reallyNow = api_get_utc_datetime(); |
||
304 | $userId = api_get_user_id(); |
||
305 | $courseId = api_get_course_int_id(); |
||
306 | $sessionId = api_get_session_id(); |
||
307 | |||
308 | return Database::insert( |
||
309 | $table, |
||
310 | [ |
||
311 | 'down_user_id' => $userId, |
||
312 | 'c_id' => $courseId, |
||
313 | 'down_doc_path' => $documentUrl, |
||
314 | 'down_date' => $reallyNow, |
||
315 | 'down_session_id' => $sessionId, |
||
316 | ] |
||
317 | ); |
||
318 | } |
||
319 | |||
320 | /** |
||
321 | * @param int $documentId of document (id in mainDb.document table) |
||
322 | * |
||
323 | * @author Sebastien Piraux <[email protected]> |
||
324 | * @desc Record information for upload event |
||
325 | * used in the works tool to record informations when |
||
326 | * an user upload 1 work |
||
327 | * |
||
328 | * @return int |
||
329 | */ |
||
330 | public static function event_upload($documentId) |
||
362 | } |
||
363 | |||
364 | /** |
||
365 | * Record information for link event (when an user click on an added link) |
||
366 | * it will be used in a redirection page. |
||
367 | * |
||
368 | * @param int $linkId (id in c_link table) |
||
369 | * |
||
370 | * @return int |
||
371 | * |
||
372 | * @author Sebastien Piraux <[email protected]> |
||
373 | */ |
||
374 | public static function event_link($linkId) |
||
402 | } |
||
403 | |||
404 | /** |
||
405 | * Update the TRACK_E_EXERCICES exercises. |
||
406 | * Record result of user when an exercise was done. |
||
407 | * |
||
408 | * @param int $exeId |
||
409 | * @param int $exoId |
||
410 | * @param mixed $score |
||
411 | * @param int $weighting |
||
412 | * @param int $sessionId |
||
413 | * @param int $learnpathId |
||
414 | * @param int $learnpathItemId |
||
415 | * @param int $learnpathItemViewId |
||
416 | * @param int $duration |
||
417 | * @param array $questionsList |
||
418 | * @param string $status |
||
419 | * @param array $remindList |
||
420 | * @param null $endDate |
||
|
|||
421 | * |
||
422 | * @return bool |
||
423 | * |
||
424 | * @author Sebastien Piraux <[email protected]> |
||
425 | * @author Julio Montoya Armas <[email protected]> Reworked 2010 |
||
426 | */ |
||
427 | public static function updateEventExercise( |
||
428 | $exeId, |
||
429 | $exoId, |
||
430 | $score, |
||
431 | $weighting, |
||
432 | $sessionId, |
||
433 | $learnpathId = 0, |
||
434 | $learnpathItemId = 0, |
||
435 | $learnpathItemViewId = 0, |
||
436 | $duration = 0, |
||
437 | $questionsList = [], |
||
438 | $status = '', |
||
439 | $remindList = [], |
||
440 | $endDate = null |
||
441 | ) { |
||
442 | if (empty($exeId)) { |
||
443 | return false; |
||
444 | } |
||
445 | if (!isset($status) || empty($status)) { |
||
446 | $status = ''; |
||
447 | } else { |
||
448 | $status = Database::escape_string($status); |
||
449 | } |
||
450 | |||
451 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
452 | |||
453 | if (!empty($questionsList)) { |
||
454 | $questionsList = array_map('intval', $questionsList); |
||
455 | } |
||
456 | |||
457 | if (!empty($remindList)) { |
||
458 | $remindList = array_map('intval', $remindList); |
||
459 | $remindList = array_filter($remindList); |
||
460 | $remindList = implode(",", $remindList); |
||
461 | } else { |
||
462 | $remindList = ''; |
||
463 | } |
||
464 | |||
465 | if (empty($endDate)) { |
||
466 | $endDate = api_get_utc_datetime(); |
||
467 | } |
||
468 | $exoId = (int) $exoId; |
||
469 | $sessionId = (int) $sessionId; |
||
470 | $learnpathId = (int) $learnpathId; |
||
471 | $learnpathItemId = (int) $learnpathItemId; |
||
472 | $learnpathItemViewId = (int) $learnpathItemViewId; |
||
473 | $duration = (int) $duration; |
||
474 | $exeId = (int) $exeId; |
||
475 | $score = Database::escape_string($score); |
||
476 | $weighting = Database::escape_string($weighting); |
||
477 | $questions = implode(',', $questionsList); |
||
478 | $userIp = Database::escape_string(api_get_real_ip()); |
||
479 | |||
480 | $sql = "UPDATE $table SET |
||
481 | exe_exo_id = $exoId, |
||
482 | exe_result = '$score', |
||
483 | exe_weighting = '$weighting', |
||
484 | session_id = $sessionId, |
||
485 | orig_lp_id = $learnpathId, |
||
486 | orig_lp_item_id = $learnpathItemId, |
||
487 | orig_lp_item_view_id = $learnpathItemViewId, |
||
488 | exe_duration = $duration, |
||
489 | exe_date = '$endDate', |
||
490 | status = '$status', |
||
491 | questions_to_check = '$remindList', |
||
492 | data_tracking = '$questions', |
||
493 | user_ip = '$userIp' |
||
494 | WHERE exe_id = $exeId"; |
||
495 | Database::query($sql); |
||
496 | |||
497 | //Deleting control time session track |
||
498 | //ExerciseLib::exercise_time_control_delete($exo_id); |
||
499 | return true; |
||
500 | } |
||
501 | |||
502 | /** |
||
503 | * Record an event for this attempt at answering an exercise. |
||
504 | * |
||
505 | * @param float $score Score achieved |
||
506 | * @param string $answer Answer given |
||
507 | * @param int $question_id |
||
508 | * @param int $exe_id Exercise attempt ID a.k.a exe_id (from track_e_exercise) |
||
509 | * @param int $position |
||
510 | * @param int $exercise_id From c_quiz |
||
511 | * @param bool $updateResults |
||
512 | * @param int $duration Time spent in seconds |
||
513 | * @param string $fileName Filename (for audio answers - using nanogong) |
||
514 | * @param int $user_id The user who's going to get this score. |
||
515 | * @param int $course_id Default value of null means "get from context". |
||
516 | * @param int $session_id Default value of null means "get from context". |
||
517 | * @param int $learnpath_id (from c_lp table). Default value of null means "get from context". |
||
518 | * @param int $learnpath_item_id (from the c_lp_item table). Default value of null means "get from context". |
||
519 | * |
||
520 | * @return bool Result of the insert query |
||
521 | */ |
||
522 | public static function saveQuestionAttempt( |
||
523 | $score, |
||
524 | $answer, |
||
525 | $question_id, |
||
526 | $exe_id, |
||
527 | $position, |
||
528 | $exercise_id = 0, |
||
529 | $updateResults = false, |
||
530 | $questionDuration = 0, |
||
531 | $fileName = null, |
||
532 | $user_id = null, |
||
533 | $course_id = null, |
||
534 | $session_id = null, |
||
535 | $learnpath_id = null, |
||
536 | $learnpath_item_id = null |
||
537 | ) { |
||
538 | global $debug; |
||
539 | $questionDuration = (int) $questionDuration; |
||
540 | $question_id = (int) $question_id; |
||
541 | $exe_id = (int) $exe_id; |
||
542 | $position = (int) $position; |
||
543 | $course_id = (int) $course_id; |
||
544 | $now = api_get_utc_datetime(); |
||
545 | $recording = api_get_configuration_value('quiz_answer_extra_recording'); |
||
546 | |||
547 | // check user_id or get from context |
||
548 | if (empty($user_id)) { |
||
549 | $user_id = api_get_user_id(); |
||
550 | // anonymous |
||
551 | if (empty($user_id)) { |
||
552 | $user_id = api_get_anonymous_id(); |
||
553 | } |
||
554 | } |
||
555 | // check course_id or get from context |
||
556 | if (empty($course_id)) { |
||
557 | $course_id = api_get_course_int_id(); |
||
558 | } |
||
559 | // check session_id or get from context |
||
560 | $session_id = (int) $session_id; |
||
561 | if (empty($session_id)) { |
||
562 | $session_id = api_get_session_id(); |
||
563 | } |
||
564 | // check learnpath_id or get from context |
||
565 | if (empty($learnpath_id)) { |
||
566 | global $learnpath_id; |
||
567 | } |
||
568 | // check learnpath_item_id or get from context |
||
569 | if (empty($learnpath_item_id)) { |
||
570 | global $learnpath_item_id; |
||
571 | } |
||
572 | |||
573 | $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
574 | |||
575 | if ($debug) { |
||
576 | error_log("----- entering saveQuestionAttempt() function ------"); |
||
577 | error_log("answer: $answer"); |
||
578 | error_log("score: $score"); |
||
579 | error_log("question_id : $question_id"); |
||
580 | error_log("position: $position"); |
||
581 | } |
||
582 | |||
583 | // Validation in case of fraud with active control time. |
||
584 | if (!ExerciseLib::exercise_time_control_is_valid($exercise_id, $learnpath_id, $learnpath_item_id)) { |
||
585 | if ($debug) { |
||
586 | error_log("exercise_time_control_is_valid is false"); |
||
587 | } |
||
588 | $score = 0; |
||
589 | $answer = 0; |
||
590 | } |
||
591 | |||
592 | if (empty($question_id) || empty($exe_id) || empty($user_id)) { |
||
593 | return false; |
||
594 | } |
||
595 | |||
596 | if (null === $answer) { |
||
597 | $answer = ''; |
||
598 | } |
||
599 | |||
600 | if (null === $score) { |
||
601 | $score = 0; |
||
602 | } |
||
603 | |||
604 | $attempt = [ |
||
605 | 'user_id' => $user_id, |
||
606 | 'question_id' => $question_id, |
||
607 | 'answer' => $answer, |
||
608 | 'marks' => $score, |
||
609 | 'c_id' => $course_id, |
||
610 | 'session_id' => $session_id, |
||
611 | 'position' => $position, |
||
612 | 'tms' => $now, |
||
613 | 'filename' => !empty($fileName) ? basename($fileName) : $fileName, |
||
614 | 'teacher_comment' => '', |
||
615 | ]; |
||
616 | |||
617 | if (api_get_configuration_value('allow_time_per_question')) { |
||
618 | $attempt['seconds_spent'] = $questionDuration; |
||
619 | } |
||
620 | |||
621 | // Check if attempt exists. |
||
622 | $sql = "SELECT exe_id FROM $TBL_TRACK_ATTEMPT |
||
623 | WHERE |
||
624 | c_id = $course_id AND |
||
625 | session_id = $session_id AND |
||
626 | exe_id = $exe_id AND |
||
627 | user_id = $user_id AND |
||
628 | question_id = $question_id AND |
||
629 | position = $position"; |
||
630 | $result = Database::query($sql); |
||
631 | $attemptData = []; |
||
632 | if (Database::num_rows($result)) { |
||
633 | $attemptData = Database::fetch_array($result, 'ASSOC'); |
||
634 | if ($updateResults == false) { |
||
635 | // The attempt already exist do not update use update_event_exercise() instead |
||
636 | return false; |
||
637 | } |
||
638 | } else { |
||
639 | $attempt['exe_id'] = $exe_id; |
||
640 | } |
||
641 | |||
642 | if ($debug) { |
||
643 | error_log("updateResults : $updateResults"); |
||
644 | error_log("Saving question attempt: "); |
||
645 | error_log($sql); |
||
646 | } |
||
647 | |||
648 | $recording_table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); |
||
649 | if ($updateResults == false) { |
||
650 | $attempt_id = Database::insert($TBL_TRACK_ATTEMPT, $attempt); |
||
651 | if ($recording) { |
||
652 | $attempt_recording = [ |
||
653 | 'exe_id' => $exe_id, |
||
654 | 'question_id' => $question_id, |
||
655 | 'answer' => $answer, |
||
656 | 'marks' => $score, |
||
657 | 'insert_date' => $now, |
||
658 | 'session_id' => $session_id, |
||
659 | ]; |
||
660 | Database::insert($recording_table, $attempt_recording); |
||
661 | } |
||
662 | } else { |
||
663 | if (api_get_configuration_value('allow_time_per_question')) { |
||
664 | $attempt['seconds_spent'] = $questionDuration + (int) $attemptData['seconds_spent']; |
||
665 | } |
||
666 | Database::update( |
||
667 | $TBL_TRACK_ATTEMPT, |
||
668 | $attempt, |
||
669 | [ |
||
670 | 'exe_id = ? AND question_id = ? AND user_id = ? ' => [ |
||
671 | $exe_id, |
||
672 | $question_id, |
||
673 | $user_id, |
||
674 | ], |
||
675 | ] |
||
676 | ); |
||
677 | |||
678 | if ($recording) { |
||
679 | $attempt_recording = [ |
||
680 | 'exe_id' => $exe_id, |
||
681 | 'question_id' => $question_id, |
||
682 | 'answer' => $answer, |
||
683 | 'marks' => $score, |
||
684 | 'insert_date' => $now, |
||
685 | 'session_id' => $session_id, |
||
686 | ]; |
||
687 | |||
688 | Database::update( |
||
689 | $recording_table, |
||
690 | $attempt_recording, |
||
691 | [ |
||
692 | 'exe_id = ? AND question_id = ? AND session_id = ? ' => [ |
||
693 | $exe_id, |
||
694 | $question_id, |
||
695 | $session_id, |
||
696 | ], |
||
697 | ] |
||
698 | ); |
||
699 | } |
||
700 | $attempt_id = $exe_id; |
||
701 | } |
||
702 | |||
703 | return $attempt_id; |
||
704 | } |
||
705 | |||
706 | /** |
||
707 | * Record an hotspot spot for this attempt at answering an hotspot question. |
||
708 | * |
||
709 | * @param int $exeId |
||
710 | * @param int $questionId Question ID |
||
711 | * @param int $answerId Answer ID |
||
712 | * @param int $correct |
||
713 | * @param string $coords Coordinates of this point (e.g. 123;324) |
||
714 | * @param bool $updateResults |
||
715 | * @param int $exerciseId |
||
716 | * |
||
717 | * @return bool Result of the insert query |
||
718 | * |
||
719 | * @uses \Course code and user_id from global scope $_cid and $_user |
||
720 | */ |
||
721 | public static function saveExerciseAttemptHotspot( |
||
722 | $exeId, |
||
723 | $questionId, |
||
724 | $answerId, |
||
725 | $correct, |
||
726 | $coords, |
||
727 | $updateResults = false, |
||
728 | $exerciseId = 0, |
||
729 | $lpId = 0, |
||
730 | $lpItemId = 0 |
||
731 | ) { |
||
732 | $debug = false; |
||
733 | |||
734 | if ($updateResults == false) { |
||
735 | // Validation in case of fraud with activated control time |
||
736 | if (!ExerciseLib::exercise_time_control_is_valid($exerciseId, $lpId, $lpItemId)) { |
||
737 | if ($debug) { |
||
738 | error_log('Attempt is fraud'); |
||
739 | } |
||
740 | $correct = 0; |
||
741 | } |
||
742 | } |
||
743 | |||
744 | if (empty($exeId)) { |
||
745 | if ($debug) { |
||
746 | error_log('exe id is empty'); |
||
747 | } |
||
748 | |||
749 | return false; |
||
750 | } |
||
751 | |||
752 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); |
||
753 | if ($updateResults) { |
||
754 | if ($debug) { |
||
755 | error_log("Insert hotspot results: exeId: $exeId correct: $correct"); |
||
756 | } |
||
757 | $params = [ |
||
758 | 'hotspot_correct' => $correct, |
||
759 | 'hotspot_coordinate' => $coords, |
||
760 | ]; |
||
761 | Database::update( |
||
762 | $table, |
||
763 | $params, |
||
764 | [ |
||
765 | 'hotspot_user_id = ? AND hotspot_exe_id = ? AND hotspot_question_id = ? AND hotspot_answer_id = ? ' => [ |
||
766 | api_get_user_id(), |
||
767 | $exeId, |
||
768 | $questionId, |
||
769 | $answerId, |
||
770 | ], |
||
771 | ] |
||
772 | ); |
||
773 | } else { |
||
774 | if ($debug) { |
||
775 | error_log("Insert hotspot results: exeId: $exeId correct: $correct"); |
||
776 | } |
||
777 | |||
778 | return Database::insert( |
||
779 | $table, |
||
780 | [ |
||
781 | 'hotspot_course_code' => api_get_course_id(), |
||
782 | 'hotspot_user_id' => api_get_user_id(), |
||
783 | 'c_id' => api_get_course_int_id(), |
||
784 | 'hotspot_exe_id' => $exeId, |
||
785 | 'hotspot_question_id' => $questionId, |
||
786 | 'hotspot_answer_id' => $answerId, |
||
787 | 'hotspot_correct' => $correct, |
||
788 | 'hotspot_coordinate' => $coords, |
||
789 | ] |
||
790 | ); |
||
791 | } |
||
792 | } |
||
793 | |||
794 | /** |
||
795 | * Records information for common (or admin) events (in the track_e_default table). |
||
796 | * |
||
797 | * @author Yannick Warnier <[email protected]> |
||
798 | * |
||
799 | * @param string $event_type Type of event |
||
800 | * @param string $event_value_type Type of value |
||
801 | * @param mixed $event_value Value (string, or array in the case of user info) |
||
802 | * @param string $datetime Datetime (UTC) (defaults to null) |
||
803 | * @param int $user_id User ID (defaults to null) |
||
804 | * @param int $course_id Course ID (defaults to null) |
||
805 | * @param int $sessionId Session ID |
||
806 | * |
||
807 | * @return bool |
||
808 | * @assert ('','','') === false |
||
809 | */ |
||
810 | public static function addEvent( |
||
884 | } |
||
885 | |||
886 | public static function findUserSubscriptionToCourse(int $userId, int $courseId, int $sessionId = 0) |
||
887 | { |
||
903 | ); |
||
904 | } |
||
905 | |||
906 | /** |
||
907 | * Get every email stored in the database. |
||
908 | * |
||
909 | * @deprecated |
||
910 | * |
||
911 | * @return array |
||
912 | * @assert () !== false |
||
913 | */ |
||
914 | public static function get_all_event_types() |
||
915 | { |
||
916 | global $event_config; |
||
917 | |||
918 | $sql = 'SELECT etm.id, event_type_name, activated, language_id, message, subject, dokeos_folder |
||
919 | FROM '.Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE).' etm |
||
920 | INNER JOIN '.Database::get_main_table(TABLE_MAIN_LANGUAGE).' l |
||
921 | ON etm.language_id = l.id'; |
||
922 | |||
923 | $events_types = Database::store_result(Database::query($sql), 'ASSOC'); |
||
924 | |||
925 | $to_return = []; |
||
926 | foreach ($events_types as $et) { |
||
927 | $et['nameLangVar'] = $event_config[$et["event_type_name"]]["name_lang_var"]; |
||
928 | $et['descLangVar'] = $event_config[$et["event_type_name"]]["desc_lang_var"]; |
||
929 | $to_return[] = $et; |
||
930 | } |
||
931 | |||
932 | return $to_return; |
||
933 | } |
||
934 | |||
935 | /** |
||
936 | * Get the users related to one event. |
||
937 | * |
||
938 | * @param string $event_name |
||
939 | * |
||
940 | * @return string |
||
941 | */ |
||
942 | public static function get_event_users($event_name) |
||
943 | { |
||
944 | $event_name = Database::escape_string($event_name); |
||
945 | $sql = 'SELECT user.user_id, user.firstname, user.lastname |
||
946 | FROM '.Database::get_main_table(TABLE_MAIN_USER).' user |
||
947 | JOIN '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' relUser |
||
948 | ON relUser.user_id = user.user_id |
||
949 | WHERE user.status <> '.ANONYMOUS.' AND relUser.event_type_name = "'.$event_name.'"'; |
||
950 | $user_list = Database::store_result(Database::query($sql), 'ASSOC'); |
||
951 | |||
952 | return json_encode($user_list); |
||
953 | } |
||
954 | |||
955 | /** |
||
956 | * @param int $user_id |
||
957 | * @param string $event_type |
||
958 | * |
||
959 | * @return array|bool |
||
960 | */ |
||
961 | public static function get_events_by_user_and_type($user_id, $event_type) |
||
962 | { |
||
963 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_DEFAULT); |
||
964 | $user_id = (int) $user_id; |
||
965 | $event_type = Database::escape_string($event_type); |
||
966 | |||
967 | $sql = "SELECT * FROM $table |
||
968 | WHERE default_value_type = 'user_id' AND |
||
969 | default_value = $user_id AND |
||
970 | default_event_type = '$event_type' |
||
971 | ORDER BY default_date "; |
||
972 | $result = Database::query($sql); |
||
973 | if ($result) { |
||
974 | return Database::store_result($result, 'ASSOC'); |
||
975 | } |
||
976 | |||
977 | return false; |
||
978 | } |
||
979 | |||
980 | /** |
||
981 | * Save the new message for one event and for one language. |
||
982 | * |
||
983 | * @param string $event_name |
||
984 | * @param array $users |
||
985 | * @param string $message |
||
986 | * @param string $subject |
||
987 | * @param string $event_message_language |
||
988 | * @param int $activated |
||
989 | */ |
||
990 | public static function save_event_type_message( |
||
991 | $event_name, |
||
992 | $users, |
||
993 | $message, |
||
994 | $subject, |
||
995 | $event_message_language, |
||
996 | $activated |
||
997 | ) { |
||
998 | $event_name = Database::escape_string($event_name); |
||
999 | $activated = (int) $activated; |
||
1000 | $event_message_language = Database::escape_string($event_message_language); |
||
1001 | |||
1002 | // Deletes then re-adds the users linked to the event |
||
1003 | $sql = 'DELETE FROM '.Database::get_main_table(TABLE_EVENT_TYPE_REL_USER).' |
||
1004 | WHERE event_type_name = "'.$event_name.'" '; |
||
1005 | Database::query($sql); |
||
1006 | |||
1007 | $eventTable = Database::get_main_table(TABLE_EVENT_TYPE_REL_USER); |
||
1008 | |||
1009 | foreach ($users as $user) { |
||
1010 | $user = (int) $user; |
||
1011 | $sql = "INSERT INTO $eventTable (user_id,event_type_name) |
||
1012 | VALUES($user,'$event_name')"; |
||
1013 | Database::query($sql); |
||
1014 | } |
||
1015 | $language_id = api_get_language_id($event_message_language); |
||
1016 | // check if this template in this language already exists or not |
||
1017 | $eventMailTable = Database::get_main_table(TABLE_EVENT_EMAIL_TEMPLATE); |
||
1018 | $sql = "SELECT COUNT(id) as total |
||
1019 | FROM $eventMailTable |
||
1020 | WHERE event_type_name = '$event_name' AND language_id = $language_id"; |
||
1021 | |||
1022 | $sql = Database::store_result(Database::query($sql), 'ASSOC'); |
||
1023 | |||
1024 | $languageTable = Database::get_main_table(TABLE_MAIN_LANGUAGE); |
||
1025 | $message = Database::escape_string($message); |
||
1026 | $subject = Database::escape_string($subject); |
||
1027 | // if already exists, we update |
||
1028 | if ($sql[0]["total"] > 0) { |
||
1029 | $sql = "UPDATE $eventMailTable |
||
1030 | SET message = '$message', |
||
1031 | subject = '$subject', |
||
1032 | activated = $activated |
||
1033 | WHERE event_type_name = '$event_name' AND language_id = ( |
||
1034 | SELECT id FROM $languageTable |
||
1035 | WHERE dokeos_folder = '$event_message_language' |
||
1036 | )"; |
||
1037 | Database::query($sql); |
||
1038 | } else { // else we create a new record |
||
1039 | // gets the language_-_id |
||
1040 | $lang_id = "(SELECT id FROM $languageTable |
||
1041 | WHERE dokeos_folder = '$event_message_language')"; |
||
1042 | $lang_id = Database::store_result(Database::query($lang_id), 'ASSOC'); |
||
1043 | $lang_id = $lang_id[0]['id']; |
||
1044 | |||
1045 | if (!empty($lang_id[0]["id"])) { |
||
1046 | $sql = "INSERT INTO $eventMailTable (event_type_name, language_id, message, subject, activated) |
||
1047 | VALUES ('$event_name', $lang_id, '$message', '$subject', $activated)"; |
||
1048 | Database::query($sql); |
||
1049 | } |
||
1050 | } |
||
1051 | |||
1052 | // set activated at every save |
||
1053 | $sql = "UPDATE $eventMailTable |
||
1054 | SET activated = $activated |
||
1055 | WHERE event_type_name = '$event_name'"; |
||
1056 | Database::query($sql); |
||
1057 | } |
||
1058 | |||
1059 | /** |
||
1060 | * Gets the last attempt of an exercise based in the exe_id. |
||
1061 | * |
||
1062 | * @param int $exeId |
||
1063 | * |
||
1064 | * @return mixed |
||
1065 | */ |
||
1066 | public static function getLastAttemptDateOfExercise($exeId) |
||
1078 | } |
||
1079 | |||
1080 | /** |
||
1081 | * Gets the last attempt of an exercise based in the exe_id. |
||
1082 | * |
||
1083 | * @param int $exeId |
||
1084 | * |
||
1085 | * @return mixed |
||
1086 | */ |
||
1087 | public static function getLatestQuestionIdFromAttempt($exeId) |
||
1088 | { |
||
1089 | $exeId = (int) $exeId; |
||
1090 | $track_attempts = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1091 | $sql = "SELECT question_id FROM $track_attempts |
||
1092 | WHERE exe_id = $exeId |
||
1093 | ORDER BY tms DESC |
||
1094 | LIMIT 1"; |
||
1095 | $result = Database::query($sql); |
||
1096 | if (Database::num_rows($result)) { |
||
1097 | $row = Database::fetch_array($result); |
||
1098 | |||
1099 | return $row['question_id']; |
||
1100 | } |
||
1101 | |||
1102 | return false; |
||
1103 | } |
||
1104 | |||
1105 | /** |
||
1106 | * Gets how many attempts exists by user, exercise, learning path. |
||
1107 | * |
||
1108 | * @param int user id |
||
1109 | * @param int exercise id |
||
1110 | * @param int lp id |
||
1111 | * @param int lp item id |
||
1112 | * @param int lp item view id |
||
1113 | * |
||
1114 | * @return int |
||
1115 | */ |
||
1116 | public static function get_attempt_count( |
||
1117 | $user_id, |
||
1118 | $exerciseId, |
||
1119 | $lp_id, |
||
1120 | $lp_item_id, |
||
1121 | $lp_item_view_id |
||
1122 | ) { |
||
1123 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1124 | $user_id = (int) $user_id; |
||
1125 | $exerciseId = (int) $exerciseId; |
||
1126 | $lp_id = (int) $lp_id; |
||
1127 | $lp_item_id = (int) $lp_item_id; |
||
1128 | $lp_item_view_id = (int) $lp_item_view_id; |
||
1129 | $courseId = api_get_course_int_id(); |
||
1130 | $sessionId = api_get_session_id(); |
||
1131 | |||
1132 | $sql = "SELECT count(*) as count |
||
1133 | FROM $table |
||
1134 | WHERE |
||
1135 | exe_exo_id = $exerciseId AND |
||
1136 | exe_user_id = $user_id AND |
||
1137 | status != 'incomplete' AND |
||
1138 | orig_lp_id = $lp_id AND |
||
1139 | orig_lp_item_id = $lp_item_id AND |
||
1140 | orig_lp_item_view_id = $lp_item_view_id AND |
||
1141 | c_id = $courseId AND |
||
1142 | session_id = $sessionId"; |
||
1143 | |||
1144 | $result = Database::query($sql); |
||
1145 | if (Database::num_rows($result) > 0) { |
||
1146 | $attempt = Database::fetch_array($result, 'ASSOC'); |
||
1147 | |||
1148 | return (int) $attempt['count']; |
||
1149 | } |
||
1150 | |||
1151 | return 0; |
||
1152 | } |
||
1153 | |||
1154 | public static function getAttemptPosition( |
||
1155 | $exeId, |
||
1156 | $user_id, |
||
1157 | $exerciseId, |
||
1158 | $lp_id, |
||
1159 | $lp_item_id, |
||
1160 | $lp_item_view_id |
||
1161 | ) { |
||
1162 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1163 | $user_id = (int) $user_id; |
||
1164 | $exerciseId = (int) $exerciseId; |
||
1165 | $lp_id = (int) $lp_id; |
||
1166 | $lp_item_id = (int) $lp_item_id; |
||
1167 | $lp_item_view_id = (int) $lp_item_view_id; |
||
1168 | $courseId = api_get_course_int_id(); |
||
1169 | $sessionId = api_get_session_id(); |
||
1170 | |||
1171 | $sql = "SELECT exe_id |
||
1172 | FROM $table |
||
1173 | WHERE |
||
1174 | exe_exo_id = $exerciseId AND |
||
1175 | exe_user_id = $user_id AND |
||
1176 | status = '' AND |
||
1177 | orig_lp_id = $lp_id AND |
||
1178 | orig_lp_item_id = $lp_item_id AND |
||
1179 | orig_lp_item_view_id = $lp_item_view_id AND |
||
1180 | c_id = $courseId AND |
||
1181 | session_id = $sessionId |
||
1182 | ORDER by exe_id |
||
1183 | "; |
||
1184 | |||
1185 | $result = Database::query($sql); |
||
1186 | if (Database::num_rows($result) > 0) { |
||
1187 | $position = 1; |
||
1188 | while ($row = Database::fetch_array($result, 'ASSOC')) { |
||
1189 | if ($row['exe_id'] === $exeId) { |
||
1190 | break; |
||
1191 | } |
||
1192 | $position++; |
||
1193 | } |
||
1194 | |||
1195 | return $position; |
||
1196 | } |
||
1197 | |||
1198 | return 0; |
||
1199 | } |
||
1200 | |||
1201 | /** |
||
1202 | * @param $user_id |
||
1203 | * @param $exerciseId |
||
1204 | * @param $lp_id |
||
1205 | * @param $lp_item_id |
||
1206 | * |
||
1207 | * @return int |
||
1208 | */ |
||
1209 | public static function get_attempt_count_not_finished( |
||
1243 | } |
||
1244 | |||
1245 | /** |
||
1246 | * @param int $user_id |
||
1247 | * @param int $lp_id |
||
1248 | * @param array $course |
||
1249 | * @param int $session_id |
||
1250 | * @param bool $disconnectExerciseResultsFromLp (Replace orig_lp_* variables to null) |
||
1251 | * |
||
1252 | * @return bool |
||
1253 | */ |
||
1254 | public static function delete_student_lp_events( |
||
1377 | } |
||
1378 | |||
1379 | /** |
||
1380 | * Delete all exercise attempts (included in LP or not). |
||
1381 | * |
||
1382 | * @param int user id |
||
1383 | * @param int exercise id |
||
1384 | * @param int $course_id |
||
1385 | * @param int session id |
||
1386 | */ |
||
1387 | public static function delete_all_incomplete_attempts( |
||
1416 | ); |
||
1417 | } |
||
1418 | } |
||
1419 | |||
1420 | /** |
||
1421 | * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session. |
||
1422 | * |
||
1423 | * @param int $exercise_id |
||
1424 | * @param int $courseId |
||
1425 | * @param int $session_id |
||
1426 | * |
||
1427 | * @return array with the results |
||
1428 | */ |
||
1429 | public static function get_all_exercise_results( |
||
1430 | $exercise_id, |
||
1431 | $courseId, |
||
1432 | $session_id = 0, |
||
1433 | $load_question_list = true, |
||
1434 | $user_id = null, |
||
1435 | $groupId = 0 |
||
1436 | ) { |
||
1437 | $TABLETRACK_EXERCICES = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1438 | $TBL_TRACK_ATTEMPT = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1439 | $courseId = (int) $courseId; |
||
1440 | $exercise_id = (int) $exercise_id; |
||
1441 | $session_id = (int) $session_id; |
||
1442 | $user_id = (int) $user_id; |
||
1443 | $groupId = (int) $groupId; |
||
1444 | |||
1445 | $user_condition = null; |
||
1446 | if (!empty($user_id)) { |
||
1447 | $user_condition = "AND exe_user_id = $user_id "; |
||
1448 | } |
||
1449 | |||
1450 | $courseInfo = api_get_course_info_by_id($courseId); |
||
1451 | if (empty($courseInfo)) { |
||
1452 | return []; |
||
1453 | } |
||
1454 | |||
1455 | $groupCondition = ''; |
||
1456 | if (!empty($groupId)) { |
||
1457 | $users = GroupManager::get_users($groupId, null, null, null, false, $courseId); |
||
1458 | // Check users added. |
||
1459 | if (!empty($users)) { |
||
1460 | $usersToString = implode("', '", $users); |
||
1461 | $groupCondition = " AND exe_user_id IN ('$usersToString') "; |
||
1462 | } else { |
||
1463 | // No users found in the group, then return an empty array. |
||
1464 | return []; |
||
1465 | } |
||
1466 | } |
||
1467 | |||
1468 | $sql = "SELECT * FROM $TABLETRACK_EXERCICES |
||
1469 | WHERE |
||
1470 | status = '' AND |
||
1471 | c_id = $courseId AND |
||
1472 | exe_exo_id = $exercise_id AND |
||
1473 | session_id = $session_id AND |
||
1474 | orig_lp_id = 0 AND |
||
1475 | orig_lp_item_id = 0 |
||
1476 | $user_condition |
||
1477 | $groupCondition |
||
1478 | ORDER BY exe_id"; |
||
1479 | $res = Database::query($sql); |
||
1480 | $list = []; |
||
1481 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1482 | $list[$row['exe_id']] = $row; |
||
1483 | if ($load_question_list) { |
||
1484 | $sql = "SELECT * FROM $TBL_TRACK_ATTEMPT |
||
1485 | WHERE exe_id = {$row['exe_id']}"; |
||
1486 | $res_question = Database::query($sql); |
||
1487 | while ($row_q = Database::fetch_array($res_question, 'ASSOC')) { |
||
1488 | $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; |
||
1489 | } |
||
1490 | } |
||
1491 | } |
||
1492 | |||
1493 | return $list; |
||
1494 | } |
||
1495 | |||
1496 | /** |
||
1497 | * Gets all exercise results (NO Exercises in LPs ) from a given exercise id, course, session. |
||
1498 | * |
||
1499 | * @param int $courseId |
||
1500 | * @param int $session_id |
||
1501 | * @param bool $get_count |
||
1502 | * |
||
1503 | * @return array with the results |
||
1504 | */ |
||
1505 | public static function get_all_exercise_results_by_course( |
||
1506 | $courseId, |
||
1507 | $session_id = 0, |
||
1508 | $get_count = true |
||
1509 | ) { |
||
1510 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1511 | $courseId = (int) $courseId; |
||
1512 | $session_id = (int) $session_id; |
||
1513 | |||
1514 | $select = '*'; |
||
1515 | if ($get_count) { |
||
1516 | $select = 'count(*) as count'; |
||
1517 | } |
||
1518 | $sql = "SELECT $select FROM $table_track_exercises |
||
1519 | WHERE status = '' AND |
||
1520 | c_id = $courseId AND |
||
1521 | session_id = $session_id AND |
||
1522 | orig_lp_id = 0 AND |
||
1523 | orig_lp_item_id = 0 |
||
1524 | ORDER BY exe_id"; |
||
1525 | $res = Database::query($sql); |
||
1526 | if ($get_count) { |
||
1527 | $row = Database::fetch_array($res, 'ASSOC'); |
||
1528 | |||
1529 | return $row['count']; |
||
1530 | } else { |
||
1531 | $list = []; |
||
1532 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1533 | $list[$row['exe_id']] = $row; |
||
1534 | } |
||
1535 | |||
1536 | return $list; |
||
1537 | } |
||
1538 | } |
||
1539 | |||
1540 | /** |
||
1541 | * Gets all exercise results (NO Exercises in LPs) from a given exercise id, course, session. |
||
1542 | * |
||
1543 | * @param int $user_id |
||
1544 | * @param int $courseId |
||
1545 | * @param int $session_id |
||
1546 | * |
||
1547 | * @return array with the results |
||
1548 | */ |
||
1549 | public static function get_all_exercise_results_by_user( |
||
1550 | $user_id, |
||
1551 | $courseId, |
||
1552 | $session_id = 0 |
||
1553 | ) { |
||
1554 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1555 | $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1556 | $courseId = (int) $courseId; |
||
1557 | $session_id = (int) $session_id; |
||
1558 | $user_id = (int) $user_id; |
||
1559 | |||
1560 | $sql = "SELECT * FROM $table_track_exercises |
||
1561 | WHERE |
||
1562 | status = '' AND |
||
1563 | exe_user_id = $user_id AND |
||
1564 | c_id = $courseId AND |
||
1565 | session_id = $session_id AND |
||
1566 | orig_lp_id = 0 AND |
||
1567 | orig_lp_item_id = 0 |
||
1568 | ORDER by exe_id"; |
||
1569 | |||
1570 | $res = Database::query($sql); |
||
1571 | $list = []; |
||
1572 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1573 | $list[$row['exe_id']] = $row; |
||
1574 | $sql = "SELECT * FROM $table_track_attempt |
||
1575 | WHERE exe_id = {$row['exe_id']}"; |
||
1576 | $res_question = Database::query($sql); |
||
1577 | while ($row_q = Database::fetch_array($res_question, 'ASSOC')) { |
||
1578 | $list[$row['exe_id']]['question_list'][$row_q['question_id']] = $row_q; |
||
1579 | } |
||
1580 | } |
||
1581 | |||
1582 | return $list; |
||
1583 | } |
||
1584 | |||
1585 | /** |
||
1586 | * Gets exercise results (NO Exercises in LPs) from a given exercise id, course, session. |
||
1587 | * |
||
1588 | * @param int $exe_id attempt id |
||
1589 | * @param string $status |
||
1590 | * |
||
1591 | * @return array with the results |
||
1592 | */ |
||
1593 | public static function get_exercise_results_by_attempt($exe_id, $status = null) |
||
1630 | } |
||
1631 | |||
1632 | /** |
||
1633 | * Gets exercise results (NO Exercises in LPs) from a given user, exercise id, course, session, lp_id, lp_item_id. |
||
1634 | * |
||
1635 | * @param int user id |
||
1636 | * @param int exercise id |
||
1637 | * @param int course id |
||
1638 | * @param int session id |
||
1639 | * @param int lp id |
||
1640 | * @param int lp item id |
||
1641 | * @param string order asc or desc |
||
1642 | * |
||
1643 | * @return array with the results |
||
1644 | */ |
||
1645 | public static function getExerciseResultsByUser( |
||
1646 | $user_id, |
||
1647 | $exercise_id, |
||
1648 | $courseId, |
||
1649 | $session_id = 0, |
||
1650 | $lp_id = 0, |
||
1651 | $lp_item_id = 0, |
||
1652 | $order = null |
||
1653 | ) { |
||
1654 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1655 | $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1656 | $table_track_attempt_recording = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); |
||
1657 | $courseId = (int) $courseId; |
||
1658 | $exercise_id = (int) $exercise_id; |
||
1659 | $session_id = (int) $session_id; |
||
1660 | $user_id = (int) $user_id; |
||
1661 | $lp_id = (int) $lp_id; |
||
1662 | $lp_item_id = (int) $lp_item_id; |
||
1663 | |||
1664 | if (!in_array(strtolower($order), ['asc', 'desc'])) { |
||
1665 | $order = 'asc'; |
||
1666 | } |
||
1667 | |||
1668 | $sql = "SELECT * FROM $table_track_exercises |
||
1669 | WHERE |
||
1670 | status = '' AND |
||
1671 | exe_user_id = $user_id AND |
||
1672 | c_id = $courseId AND |
||
1673 | exe_exo_id = $exercise_id AND |
||
1674 | session_id = $session_id AND |
||
1675 | orig_lp_id = $lp_id AND |
||
1676 | orig_lp_item_id = $lp_item_id |
||
1677 | ORDER by exe_id $order "; |
||
1678 | |||
1679 | $res = Database::query($sql); |
||
1680 | $list = []; |
||
1681 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1682 | // Checking if this attempt was revised by a teacher |
||
1683 | $exeId = $row['exe_id']; |
||
1684 | $sql = "SELECT exe_id FROM $table_track_attempt_recording |
||
1685 | WHERE author != '' AND exe_id = $exeId |
||
1686 | LIMIT 1"; |
||
1687 | $res_revised = Database::query($sql); |
||
1688 | $row['attempt_revised'] = 0; |
||
1689 | if (Database::num_rows($res_revised) > 0) { |
||
1690 | $row['attempt_revised'] = 1; |
||
1691 | } |
||
1692 | $row['total_percentage'] = 0; |
||
1693 | if (!empty($row['exe_weighting'])) { |
||
1694 | $row['total_percentage'] = ($row['exe_result'] / $row['exe_weighting']) * 100; |
||
1695 | } |
||
1696 | |||
1697 | $list[$row['exe_id']] = $row; |
||
1698 | $sql = "SELECT * FROM $table_track_attempt |
||
1699 | WHERE exe_id = $exeId"; |
||
1700 | $res_question = Database::query($sql); |
||
1701 | while ($row_q = Database::fetch_array($res_question, 'ASSOC')) { |
||
1702 | $list[$row['exe_id']]['question_list'][$row_q['question_id']][] = $row_q; |
||
1703 | } |
||
1704 | } |
||
1705 | |||
1706 | return $list; |
||
1707 | } |
||
1708 | |||
1709 | /** |
||
1710 | * Count exercise attempts (NO Exercises in LPs ) from a given exercise id, course, session. |
||
1711 | * |
||
1712 | * @param int $user_id |
||
1713 | * @param int $exercise_id |
||
1714 | * @param int $courseId |
||
1715 | * @param int $session_id |
||
1716 | * |
||
1717 | * @return array with the results |
||
1718 | */ |
||
1719 | public static function count_exercise_attempts_by_user( |
||
1720 | $user_id, |
||
1721 | $exercise_id, |
||
1722 | $courseId, |
||
1723 | $session_id = 0 |
||
1724 | ) { |
||
1725 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1726 | $courseId = (int) $courseId; |
||
1727 | $exercise_id = (int) $exercise_id; |
||
1728 | $session_id = (int) $session_id; |
||
1729 | $user_id = (int) $user_id; |
||
1730 | |||
1731 | $sql = "SELECT count(*) as count |
||
1732 | FROM $table |
||
1733 | WHERE status = '' AND |
||
1734 | exe_user_id = $user_id AND |
||
1735 | c_id = $courseId AND |
||
1736 | exe_exo_id = $exercise_id AND |
||
1737 | session_id = $session_id AND |
||
1738 | orig_lp_id =0 AND |
||
1739 | orig_lp_item_id = 0 |
||
1740 | ORDER BY exe_id"; |
||
1741 | $res = Database::query($sql); |
||
1742 | $result = 0; |
||
1743 | if (Database::num_rows($res) > 0) { |
||
1744 | $row = Database::fetch_array($res, 'ASSOC'); |
||
1745 | $result = $row['count']; |
||
1746 | } |
||
1747 | |||
1748 | return $result; |
||
1749 | } |
||
1750 | |||
1751 | /** |
||
1752 | * Gets all exercise BEST results attempts (NO Exercises in LPs) |
||
1753 | * from a given exercise id, course, session per user. |
||
1754 | * |
||
1755 | * @param int $exercise_id |
||
1756 | * @param int $courseId |
||
1757 | * @param int $session_id |
||
1758 | * @param int $userId |
||
1759 | * |
||
1760 | * @return array with the results |
||
1761 | * |
||
1762 | * @todo rename this function |
||
1763 | */ |
||
1764 | public static function get_best_exercise_results_by_user( |
||
1765 | $exercise_id, |
||
1766 | $courseId, |
||
1767 | $session_id = 0, |
||
1768 | $userId = 0 |
||
1769 | ) { |
||
1770 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1771 | $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1772 | $courseId = (int) $courseId; |
||
1773 | $exercise_id = (int) $exercise_id; |
||
1774 | $session_id = (int) $session_id; |
||
1775 | |||
1776 | $sql = "SELECT * FROM $table_track_exercises |
||
1777 | WHERE |
||
1778 | status = '' AND |
||
1779 | c_id = $courseId AND |
||
1780 | exe_exo_id = $exercise_id AND |
||
1781 | session_id = $session_id AND |
||
1782 | orig_lp_id = 0 AND |
||
1783 | orig_lp_item_id = 0"; |
||
1784 | |||
1785 | if (!empty($userId)) { |
||
1786 | $userId = (int) $userId; |
||
1787 | $sql .= " AND exe_user_id = $userId "; |
||
1788 | } |
||
1789 | $sql .= ' ORDER BY exe_id'; |
||
1790 | |||
1791 | $res = Database::query($sql); |
||
1792 | $list = []; |
||
1793 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1794 | $list[$row['exe_id']] = $row; |
||
1795 | $exeId = $row['exe_id']; |
||
1796 | $sql = "SELECT * FROM $table_track_attempt |
||
1797 | WHERE exe_id = $exeId"; |
||
1798 | $res_question = Database::query($sql); |
||
1799 | while ($row_q = Database::fetch_array($res_question, 'ASSOC')) { |
||
1800 | $list[$exeId]['question_list'][$row_q['question_id']] = $row_q; |
||
1801 | } |
||
1802 | } |
||
1803 | |||
1804 | // Getting the best results of every student |
||
1805 | $best_score_return = []; |
||
1806 | foreach ($list as $student_result) { |
||
1807 | $user_id = $student_result['exe_user_id']; |
||
1808 | $current_best_score[$user_id] = $student_result['exe_result']; |
||
1809 | if (!isset($best_score_return[$user_id]['exe_result'])) { |
||
1810 | $best_score_return[$user_id] = $student_result; |
||
1811 | } |
||
1812 | |||
1813 | if ($current_best_score[$user_id] > $best_score_return[$user_id]['exe_result']) { |
||
1814 | $best_score_return[$user_id] = $student_result; |
||
1815 | } |
||
1816 | } |
||
1817 | |||
1818 | return $best_score_return; |
||
1819 | } |
||
1820 | |||
1821 | /** |
||
1822 | * Get the last best result from all attempts in exercises per user (out of learning paths). |
||
1823 | * |
||
1824 | * @param int $user_id |
||
1825 | * @param int $exercise_id |
||
1826 | * @param int $courseId |
||
1827 | * @param int $session_id |
||
1828 | * @param bool $skipLpResults |
||
1829 | * |
||
1830 | * @return array |
||
1831 | */ |
||
1832 | public static function get_best_attempt_exercise_results_per_user( |
||
1833 | $user_id, |
||
1834 | $exercise_id, |
||
1835 | $courseId, |
||
1836 | $session_id = 0, |
||
1837 | $skipLpResults = true |
||
1838 | ) { |
||
1839 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1840 | $courseId = (int) $courseId; |
||
1841 | $exercise_id = (int) $exercise_id; |
||
1842 | $session_id = (int) $session_id; |
||
1843 | $user_id = (int) $user_id; |
||
1844 | |||
1845 | $sql = "SELECT * FROM $table |
||
1846 | WHERE |
||
1847 | status = '' AND |
||
1848 | c_id = $courseId AND |
||
1849 | exe_exo_id = $exercise_id AND |
||
1850 | session_id = $session_id AND |
||
1851 | exe_user_id = $user_id |
||
1852 | "; |
||
1853 | |||
1854 | if ($skipLpResults) { |
||
1855 | $sql .= ' AND |
||
1856 | orig_lp_id = 0 AND |
||
1857 | orig_lp_item_id = 0 '; |
||
1858 | } |
||
1859 | |||
1860 | $sql .= ' ORDER BY exe_id '; |
||
1861 | |||
1862 | $res = Database::query($sql); |
||
1863 | $list = []; |
||
1864 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1865 | $list[$row['exe_id']] = $row; |
||
1866 | } |
||
1867 | // Getting the best results of every student. |
||
1868 | $best_score_return = []; |
||
1869 | $best_score_return['exe_result'] = 0; |
||
1870 | |||
1871 | foreach ($list as $result) { |
||
1872 | $current_best_score = $result; |
||
1873 | if ($current_best_score['exe_result'] > $best_score_return['exe_result']) { |
||
1874 | $best_score_return = $result; |
||
1875 | } |
||
1876 | } |
||
1877 | if (!isset($best_score_return['exe_weighting'])) { |
||
1878 | $best_score_return = []; |
||
1879 | } |
||
1880 | |||
1881 | return $best_score_return; |
||
1882 | } |
||
1883 | |||
1884 | /** |
||
1885 | * @param int $exercise_id |
||
1886 | * @param int $courseId |
||
1887 | * @param int $session_id |
||
1888 | * |
||
1889 | * @return mixed |
||
1890 | */ |
||
1891 | public static function count_exercise_result_not_validated( |
||
1892 | $exercise_id, |
||
1893 | $courseId, |
||
1894 | $session_id = 0 |
||
1895 | ) { |
||
1896 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1897 | $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT_RECORDING); |
||
1898 | $courseId = (int) $courseId; |
||
1899 | $session_id = (int) $session_id; |
||
1900 | $exercise_id = (int) $exercise_id; |
||
1901 | |||
1902 | $sql = "SELECT count(e.exe_id) as count |
||
1903 | FROM $table_track_exercises e |
||
1904 | LEFT JOIN $table_track_attempt a |
||
1905 | ON e.exe_id = a.exe_id |
||
1906 | WHERE |
||
1907 | exe_exo_id = $exercise_id AND |
||
1908 | c_id = $courseId AND |
||
1909 | e.session_id = $session_id AND |
||
1910 | orig_lp_id = 0 AND |
||
1911 | marks IS NULL AND |
||
1912 | status = '' AND |
||
1913 | orig_lp_item_id = 0 |
||
1914 | ORDER BY e.exe_id"; |
||
1915 | $res = Database::query($sql); |
||
1916 | $row = Database::fetch_array($res, 'ASSOC'); |
||
1917 | |||
1918 | return $row['count']; |
||
1919 | } |
||
1920 | |||
1921 | /** |
||
1922 | * Gets all exercise events from a Learning Path within a Course nd Session. |
||
1923 | * |
||
1924 | * @param int $exercise_id |
||
1925 | * @param int $courseId |
||
1926 | * @param int $session_id |
||
1927 | * |
||
1928 | * @return array |
||
1929 | */ |
||
1930 | public static function get_all_exercise_event_from_lp( |
||
1931 | $exercise_id, |
||
1932 | $courseId, |
||
1933 | $session_id = 0 |
||
1934 | ) { |
||
1935 | $table_track_exercises = Database::get_main_table(TABLE_STATISTIC_TRACK_E_EXERCISES); |
||
1936 | $table_track_attempt = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
1937 | $courseId = (int) $courseId; |
||
1938 | $exercise_id = (int) $exercise_id; |
||
1939 | $session_id = (int) $session_id; |
||
1940 | |||
1941 | $sql = "SELECT * FROM $table_track_exercises |
||
1942 | WHERE |
||
1943 | status = '' AND |
||
1944 | c_id = $courseId AND |
||
1945 | exe_exo_id = $exercise_id AND |
||
1946 | session_id = $session_id AND |
||
1947 | orig_lp_id !=0 AND |
||
1948 | orig_lp_item_id != 0"; |
||
1949 | |||
1950 | $res = Database::query($sql); |
||
1951 | $list = []; |
||
1952 | while ($row = Database::fetch_array($res, 'ASSOC')) { |
||
1953 | $exeId = $row['exe_id']; |
||
1954 | $list[$exeId] = $row; |
||
1955 | $sql = "SELECT * FROM $table_track_attempt |
||
1956 | WHERE exe_id = $exeId"; |
||
1957 | $res_question = Database::query($sql); |
||
1958 | while ($row_q = Database::fetch_array($res_question, 'ASSOC')) { |
||
1959 | $list[$exeId]['question_list'][$row_q['question_id']] = $row_q; |
||
1960 | } |
||
1961 | } |
||
1962 | |||
1963 | return $list; |
||
1964 | } |
||
1965 | |||
1966 | /** |
||
1967 | * Get a list of all the exercises in a given learning path. |
||
1968 | * |
||
1969 | * @param int $lp_id |
||
1970 | * @param int $course_id This parameter is probably deprecated as lp_id now is a global iid |
||
1971 | * |
||
1972 | * @return array |
||
1973 | */ |
||
1974 | public static function get_all_exercises_from_lp($lp_id, $course_id) |
||
1993 | } |
||
1994 | |||
1995 | /** |
||
1996 | * This function gets the comments of an exercise. |
||
1997 | * |
||
1998 | * @param int $exe_id |
||
1999 | * @param int $question_id |
||
2000 | * |
||
2001 | * @return string the comment |
||
2002 | */ |
||
2003 | public static function get_comments($exe_id, $question_id) |
||
2004 | { |
||
2005 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
2006 | $exe_id = (int) $exe_id; |
||
2007 | $question_id = (int) $question_id; |
||
2008 | $sql = "SELECT teacher_comment |
||
2009 | FROM $table |
||
2010 | WHERE |
||
2011 | exe_id = $exe_id AND |
||
2012 | question_id = $question_id |
||
2013 | ORDER by question_id"; |
||
2014 | $sqlres = Database::query($sql); |
||
2015 | $comm = strval(Database::result($sqlres, 0, 'teacher_comment')); |
||
2016 | $comm = trim($comm); |
||
2017 | |||
2018 | return $comm; |
||
2019 | } |
||
2020 | |||
2021 | /** |
||
2022 | * Get all the track_e_attempt records for a given |
||
2023 | * track_e_exercises.exe_id (pk). |
||
2024 | * |
||
2025 | * @param int $exeId The exe_id from an exercise attempt record |
||
2026 | * |
||
2027 | * @return array The complete records from track_e_attempt that match the given exe_id |
||
2028 | */ |
||
2029 | public static function getAllExerciseEventByExeId($exeId) |
||
2030 | { |
||
2031 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
2032 | $exeId = (int) $exeId; |
||
2033 | |||
2034 | $sql = "SELECT * FROM $table |
||
2035 | WHERE exe_id = $exeId |
||
2036 | ORDER BY position"; |
||
2037 | $res_question = Database::query($sql); |
||
2038 | $list = []; |
||
2039 | if (Database::num_rows($res_question)) { |
||
2040 | while ($row = Database::fetch_array($res_question, 'ASSOC')) { |
||
2041 | $list[$row['question_id']][] = $row; |
||
2042 | } |
||
2043 | } |
||
2044 | |||
2045 | return $list; |
||
2046 | } |
||
2047 | |||
2048 | public static function getQuestionAttemptByExeIdAndQuestion($exeId, $questionId) |
||
2049 | { |
||
2050 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_ATTEMPT); |
||
2051 | $exeId = (int) $exeId; |
||
2052 | $questionId = (int) $questionId; |
||
2053 | |||
2054 | $sql = "SELECT * FROM $table |
||
2055 | WHERE |
||
2056 | exe_id = $exeId AND |
||
2057 | question_id = $questionId |
||
2058 | ORDER BY position"; |
||
2059 | $result = Database::query($sql); |
||
2060 | $attempt = []; |
||
2061 | if (Database::num_rows($result)) { |
||
2062 | $attempt = Database::fetch_array($result, 'ASSOC'); |
||
2063 | } |
||
2064 | |||
2065 | return $attempt; |
||
2066 | } |
||
2067 | |||
2068 | /** |
||
2069 | * Delete one record from the track_e_attempt table (recorded quiz answer) |
||
2070 | * and register the deletion event (LOG_QUESTION_RESULT_DELETE) in |
||
2071 | * track_e_default. |
||
2072 | * |
||
2073 | * @param int $exeId The track_e_exercises.exe_id (primary key) |
||
2074 | * @param int $user_id The user who answered (already contained in exe_id) |
||
2075 | * @param int $courseId The course in which it happened (already contained in exe_id) |
||
2076 | * @param int $session_id The session in which it happened (already contained in exe_id) |
||
2077 | * @param int $question_id The c_quiz_question.iid |
||
2078 | */ |
||
2079 | public static function delete_attempt( |
||
2111 | ); |
||
2112 | } |
||
2113 | |||
2114 | /** |
||
2115 | * Delete one record from the track_e_hotspot table based on a given |
||
2116 | * track_e_exercises.exe_id. |
||
2117 | * |
||
2118 | * @param $exeId |
||
2119 | * @param $user_id |
||
2120 | * @param int $courseId |
||
2121 | * @param $question_id |
||
2122 | * @param int $sessionId |
||
2123 | */ |
||
2124 | public static function delete_attempt_hotspot( |
||
2125 | $exeId, |
||
2126 | $user_id, |
||
2127 | $courseId, |
||
2128 | $question_id, |
||
2129 | $sessionId = null |
||
2130 | ) { |
||
2131 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_HOTSPOT); |
||
2132 | |||
2133 | $exeId = (int) $exeId; |
||
2134 | $user_id = (int) $user_id; |
||
2135 | $courseId = (int) $courseId; |
||
2136 | $question_id = (int) $question_id; |
||
2137 | if (!isset($sessionId)) { |
||
2138 | $sessionId = api_get_session_id(); |
||
2139 | } |
||
2140 | |||
2141 | $sql = "DELETE FROM $table |
||
2142 | WHERE |
||
2143 | hotspot_exe_id = $exeId AND |
||
2144 | hotspot_user_id = $user_id AND |
||
2145 | c_id = $courseId AND |
||
2146 | hotspot_question_id = $question_id "; |
||
2147 | Database::query($sql); |
||
2148 | self::addEvent( |
||
2149 | LOG_QUESTION_RESULT_DELETE, |
||
2150 | LOG_EXERCISE_ATTEMPT_QUESTION_ID, |
||
2151 | $exeId.'-'.$question_id, |
||
2152 | null, |
||
2153 | null, |
||
2154 | $courseId, |
||
2155 | $sessionId |
||
2156 | ); |
||
2157 | } |
||
2158 | |||
2159 | /** |
||
2160 | * Registers in track_e_course_access when user logs in for the first time to a course. |
||
2161 | * |
||
2162 | * @param int $courseId ID of the course |
||
2163 | * @param int $user_id ID of the user |
||
2164 | * @param int $sessionId ID of the session (if any) |
||
2165 | * |
||
2166 | * @return bool |
||
2167 | */ |
||
2168 | public static function eventCourseLogin($courseId, $user_id, $sessionId) |
||
2169 | { |
||
2170 | if (Session::read('login_as')) { |
||
2171 | return false; |
||
2172 | } |
||
2173 | |||
2174 | $sessionId = (int) $sessionId; |
||
2175 | if (self::isSessionLogNeedToBeSave($sessionId) === false) { |
||
2176 | return false; |
||
2177 | } |
||
2178 | |||
2179 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||
2180 | $loginDate = $logoutDate = api_get_utc_datetime(); |
||
2181 | |||
2182 | // $counter represents the number of time this record has been refreshed |
||
2183 | $counter = 1; |
||
2184 | $courseId = (int) $courseId; |
||
2185 | $user_id = (int) $user_id; |
||
2186 | $ip = Database::escape_string(api_get_real_ip()); |
||
2187 | |||
2188 | $sql = "INSERT INTO $table(c_id, user_ip, user_id, login_course_date, logout_course_date, counter, session_id) |
||
2189 | VALUES($courseId, '$ip', $user_id, '$loginDate', '$logoutDate', $counter, $sessionId)"; |
||
2190 | $courseAccessId = Database::query($sql); |
||
2191 | |||
2192 | if ($courseAccessId) { |
||
2193 | // Course catalog stats modifications see #4191 |
||
2194 | CourseManager::update_course_ranking( |
||
2195 | null, |
||
2196 | null, |
||
2197 | null, |
||
2198 | null, |
||
2199 | true, |
||
2200 | false |
||
2201 | ); |
||
2202 | |||
2203 | return true; |
||
2204 | } |
||
2205 | } |
||
2206 | |||
2207 | /** |
||
2208 | * Updates the user - course - session every X minutes |
||
2209 | * In order to avoid. |
||
2210 | * |
||
2211 | * @param int $courseId |
||
2212 | * @param int $userId |
||
2213 | * @param int $sessionId |
||
2214 | * @param int $minutes |
||
2215 | * |
||
2216 | * @return bool |
||
2217 | */ |
||
2218 | public static function eventCourseLoginUpdate( |
||
2219 | $courseId, |
||
2220 | $userId, |
||
2221 | $sessionId, |
||
2222 | $minutes = 5 |
||
2223 | ) { |
||
2224 | if (Session::read('login_as')) { |
||
2225 | return false; |
||
2226 | } |
||
2227 | |||
2228 | if (empty($courseId) || empty($userId)) { |
||
2229 | return false; |
||
2230 | } |
||
2231 | |||
2232 | $sessionId = (int) $sessionId; |
||
2233 | |||
2234 | if (self::isSessionLogNeedToBeSave($sessionId) === false) { |
||
2235 | return false; |
||
2236 | } |
||
2237 | |||
2238 | $courseId = (int) $courseId; |
||
2239 | $userId = (int) $userId; |
||
2240 | |||
2241 | $table = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||
2242 | $sql = "SELECT course_access_id, logout_course_date |
||
2243 | FROM $table |
||
2244 | WHERE |
||
2245 | c_id = $courseId AND |
||
2246 | session_id = $sessionId AND |
||
2247 | user_id = $userId |
||
2248 | ORDER BY login_course_date DESC |
||
2249 | LIMIT 1"; |
||
2250 | |||
2251 | $result = Database::query($sql); |
||
2252 | |||
2253 | // Save every 5 minutes by default |
||
2254 | $seconds = $minutes * 60; |
||
2255 | $maxSeconds = 3600; // Only update if max diff is one hour |
||
2256 | if (Database::num_rows($result)) { |
||
2257 | $row = Database::fetch_array($result); |
||
2258 | $id = $row['course_access_id']; |
||
2259 | $logout = $row['logout_course_date']; |
||
2260 | $now = time(); |
||
2261 | $logout = api_strtotime($logout, 'UTC'); |
||
2262 | if ($now - $logout > $seconds && |
||
2263 | $now - $logout < $maxSeconds |
||
2264 | ) { |
||
2265 | $now = api_get_utc_datetime(); |
||
2266 | $sql = "UPDATE $table SET |
||
2267 | logout_course_date = '$now', |
||
2268 | counter = counter + 1 |
||
2269 | WHERE course_access_id = $id"; |
||
2270 | Database::query($sql); |
||
2271 | } |
||
2272 | |||
2273 | return true; |
||
2274 | } |
||
2275 | |||
2276 | return false; |
||
2277 | } |
||
2278 | |||
2279 | /** |
||
2280 | * Register the logout of the course (usually when logging out of the platform) |
||
2281 | * from the track_e_course_access table. |
||
2282 | * |
||
2283 | * @param array $logoutInfo Information stored by local.inc.php |
||
2284 | * before new context ['uid'=> x, 'cid'=>y, 'sid'=>z] |
||
2285 | * |
||
2286 | * @return bool |
||
2287 | */ |
||
2288 | public static function courseLogout($logoutInfo) |
||
2289 | { |
||
2290 | if (Session::read('login_as')) { |
||
2291 | return false; |
||
2292 | } |
||
2293 | |||
2294 | if (empty($logoutInfo['uid']) || empty($logoutInfo['cid'])) { |
||
2295 | return false; |
||
2296 | } |
||
2297 | |||
2298 | $sessionLifetime = api_get_configuration_value('session_lifetime'); |
||
2299 | /* |
||
2300 | * When $_configuration['session_lifetime'] is larger than ~100 hours |
||
2301 | * (in order to let users take exercises with no problems) |
||
2302 | * the function Tracking::get_time_spent_on_the_course() returns larger values (200h) due the condition: |
||
2303 | * login_course_date > now() - INTERVAL $session_lifetime SECOND |
||
2304 | */ |
||
2305 | if (empty($sessionLifetime) || $sessionLifetime > 86400) { |
||
2306 | $sessionLifetime = 3600; // 1 hour |
||
2307 | } |
||
2308 | if (!empty($logoutInfo) && !empty($logoutInfo['cid'])) { |
||
2309 | $sessionId = 0; |
||
2310 | if (!empty($logoutInfo['sid'])) { |
||
2311 | $sessionId = (int) $logoutInfo['sid']; |
||
2312 | } |
||
2313 | |||
2314 | if (self::isSessionLogNeedToBeSave($sessionId) === false) { |
||
2315 | return false; |
||
2316 | } |
||
2317 | |||
2318 | $tableCourseAccess = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||
2319 | $userId = (int) $logoutInfo['uid']; |
||
2320 | $courseId = (int) $logoutInfo['cid']; |
||
2321 | |||
2322 | $currentDate = api_get_utc_datetime(); |
||
2323 | // UTC time |
||
2324 | $diff = time() - $sessionLifetime; |
||
2325 | $time = api_get_utc_datetime($diff); |
||
2326 | $sql = "SELECT course_access_id, logout_course_date |
||
2327 | FROM $tableCourseAccess |
||
2328 | WHERE |
||
2329 | user_id = $userId AND |
||
2330 | c_id = $courseId AND |
||
2331 | session_id = $sessionId AND |
||
2332 | login_course_date > '$time' |
||
2333 | ORDER BY login_course_date DESC |
||
2334 | LIMIT 1"; |
||
2335 | $result = Database::query($sql); |
||
2336 | $insert = false; |
||
2337 | if (Database::num_rows($result) > 0) { |
||
2338 | $row = Database::fetch_array($result, 'ASSOC'); |
||
2339 | $courseAccessId = $row['course_access_id']; |
||
2340 | $sql = "UPDATE $tableCourseAccess SET |
||
2341 | logout_course_date = '$currentDate', |
||
2342 | counter = counter + 1 |
||
2343 | WHERE course_access_id = $courseAccessId"; |
||
2344 | Database::query($sql); |
||
2345 | } else { |
||
2346 | $insert = true; |
||
2347 | } |
||
2348 | |||
2349 | if ($insert) { |
||
2350 | $ip = Database::escape_string(api_get_real_ip()); |
||
2351 | $sql = "INSERT INTO $tableCourseAccess (c_id, user_ip, user_id, login_course_date, logout_course_date, counter, session_id) |
||
2352 | VALUES ($courseId, '$ip', $userId, '$currentDate', '$currentDate', 1, $sessionId)"; |
||
2353 | Database::query($sql); |
||
2354 | } |
||
2355 | |||
2356 | return true; |
||
2357 | } |
||
2358 | } |
||
2359 | |||
2360 | /** |
||
2361 | * Register a "fake" time spent on the platform, for example to match the |
||
2362 | * estimated time he took to author an assignment/work, see configuration |
||
2363 | * setting considered_working_time. |
||
2364 | * This assumes there is already some connection of the student to the |
||
2365 | * course, otherwise he wouldn't be able to upload an assignment. |
||
2366 | * This works by creating a new record, copy of the current one, then |
||
2367 | * updating the current one to be just the considered_working_time and |
||
2368 | * end at the same second as the user connected to the course. |
||
2369 | * |
||
2370 | * @param int $courseId The course in which to add the time |
||
2371 | * @param int $userId The user for whom to add the time |
||
2372 | * @param int $sessionId The session in which to add the time (if any) |
||
2373 | * @param string $virtualTime The amount of time to be added, |
||
2374 | * in a hh:mm:ss format. If int, we consider it is expressed in hours. |
||
2375 | * @param int $workId Student publication id result |
||
2376 | * |
||
2377 | * @return true on successful insertion, false otherwise |
||
2378 | */ |
||
2379 | public static function eventAddVirtualCourseTime( |
||
2380 | $courseId, |
||
2381 | $userId, |
||
2382 | $sessionId, |
||
2383 | $virtualTime, |
||
2384 | $workId |
||
2385 | ) { |
||
2386 | if (empty($virtualTime)) { |
||
2387 | return false; |
||
2388 | } |
||
2389 | |||
2390 | $courseId = (int) $courseId; |
||
2391 | $userId = (int) $userId; |
||
2392 | $sessionId = (int) $sessionId; |
||
2393 | |||
2394 | $logoutDate = api_get_utc_datetime(); |
||
2395 | $loginDate = ChamiloApi::addOrSubTimeToDateTime( |
||
2396 | $virtualTime, |
||
2397 | $logoutDate, |
||
2398 | false |
||
2399 | ); |
||
2400 | |||
2401 | $ip = api_get_real_ip(); |
||
2402 | $params = [ |
||
2403 | 'login_course_date' => $loginDate, |
||
2404 | 'logout_course_date' => $logoutDate, |
||
2405 | 'session_id' => $sessionId, |
||
2406 | 'user_id' => $userId, |
||
2407 | 'counter' => 0, |
||
2408 | 'c_id' => $courseId, |
||
2409 | 'user_ip' => $ip, |
||
2410 | ]; |
||
2411 | $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||
2412 | Database::insert($courseTrackingTable, $params); |
||
2413 | |||
2414 | // Time should also be added to the track_e_login table so as to |
||
2415 | // affect total time on the platform |
||
2416 | $params = [ |
||
2417 | 'login_user_id' => $userId, |
||
2418 | 'login_date' => $loginDate, |
||
2419 | 'user_ip' => $ip, |
||
2420 | 'logout_date' => $logoutDate, |
||
2421 | ]; |
||
2422 | $platformTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); |
||
2423 | Database::insert($platformTrackingTable, $params); |
||
2424 | |||
2425 | if (Tracking::minimumTimeAvailable($sessionId, $courseId)) { |
||
2426 | $workId = (int) $workId; |
||
2427 | $uniqueId = time(); |
||
2428 | $logInfo = [ |
||
2429 | 'c_id' => $courseId, |
||
2430 | 'session_id' => $sessionId, |
||
2431 | 'tool' => TOOL_STUDENTPUBLICATION, |
||
2432 | 'date_reg' => $loginDate, |
||
2433 | 'action' => 'add_work_start_'.$workId, |
||
2434 | 'action_details' => $virtualTime, |
||
2435 | 'user_id' => $userId, |
||
2436 | 'current_id' => $uniqueId, |
||
2437 | ]; |
||
2438 | self::registerLog($logInfo); |
||
2439 | |||
2440 | $logInfo = [ |
||
2441 | 'c_id' => $courseId, |
||
2442 | 'session_id' => $sessionId, |
||
2443 | 'tool' => TOOL_STUDENTPUBLICATION, |
||
2444 | 'date_reg' => $logoutDate, |
||
2445 | 'action' => 'add_work_end_'.$workId, |
||
2446 | 'action_details' => $virtualTime, |
||
2447 | 'user_id' => $userId, |
||
2448 | 'current_id' => $uniqueId, |
||
2449 | ]; |
||
2450 | self::registerLog($logInfo); |
||
2451 | } |
||
2452 | |||
2453 | return true; |
||
2454 | } |
||
2455 | |||
2456 | /** |
||
2457 | * Removes a "fake" time spent on the platform, for example to match the |
||
2458 | * estimated time he took to author an assignment/work, see configuration |
||
2459 | * setting considered_working_time. |
||
2460 | * This method should be called when something that generated a fake |
||
2461 | * time record is removed. Given the database link is weak (no real |
||
2462 | * relationship kept between the deleted item and this record), this |
||
2463 | * method just looks for the latest record that has the same time as the |
||
2464 | * item's fake time, is in the past and in this course+session. If such a |
||
2465 | * record cannot be found, it doesn't do anything. |
||
2466 | * The IP address is not considered a useful filter here. |
||
2467 | * |
||
2468 | * @param int $courseId The course in which to add the time |
||
2469 | * @param int $userId The user for whom to add the time |
||
2470 | * @param int $sessionId The session in which to add the time (if any) |
||
2471 | * @param string $virtualTime The amount of time to be added, in a hh:mm:ss format. If int, we consider it is expressed in hours. |
||
2472 | * |
||
2473 | * @return true on successful removal, false otherwise |
||
2474 | */ |
||
2475 | public static function eventRemoveVirtualCourseTime( |
||
2476 | $courseId, |
||
2477 | $userId, |
||
2478 | $sessionId, |
||
2479 | $virtualTime, |
||
2480 | $workId |
||
2481 | ) { |
||
2482 | if (empty($virtualTime)) { |
||
2483 | return false; |
||
2484 | } |
||
2485 | |||
2486 | $courseId = (int) $courseId; |
||
2487 | $userId = (int) $userId; |
||
2488 | $sessionId = (int) $sessionId; |
||
2489 | $originalVirtualTime = Database::escape_string($virtualTime); |
||
2490 | $workId = (int) $workId; |
||
2491 | |||
2492 | $courseTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_COURSE_ACCESS); |
||
2493 | $platformTrackingTable = Database::get_main_table(TABLE_STATISTIC_TRACK_E_LOGIN); |
||
2494 | |||
2495 | // Change $virtualTime format from hh:mm:ss to hhmmss which is the |
||
2496 | // format returned by SQL for a subtraction of two datetime values |
||
2497 | // @todo make sure this is portable between DBMSes |
||
2498 | if (preg_match('/:/', $virtualTime)) { |
||
2499 | [$h, $m, $s] = preg_split('/:/', $virtualTime); |
||
2500 | $virtualTime = $h * 3600 + $m * 60 + $s; |
||
2501 | } else { |
||
2502 | $virtualTime *= 3600; |
||
2503 | } |
||
2504 | |||
2505 | // Get the current latest course connection register. We need that |
||
2506 | // record to re-use the data and create a new record. |
||
2507 | $sql = "SELECT course_access_id |
||
2508 | FROM $courseTrackingTable |
||
2509 | WHERE |
||
2510 | user_id = $userId AND |
||
2511 | c_id = $courseId AND |
||
2512 | session_id = $sessionId AND |
||
2513 | counter = 0 AND |
||
2514 | (UNIX_TIMESTAMP(logout_course_date) - UNIX_TIMESTAMP(login_course_date)) = '$virtualTime' |
||
2515 | ORDER BY login_course_date DESC LIMIT 0,1"; |
||
2516 | $result = Database::query($sql); |
||
2517 | |||
2518 | // Ignore if we didn't find any course connection record in the last |
||
2519 | // hour. In this case it wouldn't be right to add a "fake" time record. |
||
2520 | if (Database::num_rows($result) > 0) { |
||
2521 | // Found the latest connection |
||
2522 | $row = Database::fetch_row($result); |
||
2523 | $courseAccessId = $row[0]; |
||
2524 | $sql = "DELETE FROM $courseTrackingTable |
||
2525 | WHERE course_access_id = $courseAccessId"; |
||
2526 | Database::query($sql); |
||
2527 | } |
||
2528 | $sql = "SELECT login_id |
||
2529 | FROM $platformTrackingTable |
||
2530 | WHERE |
||
2531 | login_user_id = $userId AND |
||
2532 | (UNIX_TIMESTAMP(logout_date) - UNIX_TIMESTAMP(login_date)) = '$virtualTime' |
||
2533 | ORDER BY login_date DESC LIMIT 0,1"; |
||
2534 | $result = Database::query($sql); |
||
2535 | if (Database::num_rows($result) > 0) { |
||
2536 | // Found the latest connection |
||
2537 | $row = Database::fetch_row($result); |
||
2538 | $loginAccessId = $row[0]; |
||
2539 | $sql = "DELETE FROM $platformTrackingTable |
||
2540 | WHERE login_id = $loginAccessId"; |
||
2541 | Database::query($sql); |
||
2542 | } |
||
2543 | |||
2544 | if (Tracking::minimumTimeAvailable($sessionId, $courseId)) { |
||
2545 | $sql = "SELECT id FROM track_e_access_complete |
||
2546 | WHERE |
||
2547 | tool = '".TOOL_STUDENTPUBLICATION."' AND |
||
2548 | c_id = $courseId AND |
||
2549 | session_id = $sessionId AND |
||
2550 | user_id = $userId AND |
||
2551 | action_details = '$originalVirtualTime' AND |
||
2552 | action = 'add_work_start_$workId' "; |
||
2553 | $result = Database::query($sql); |
||
2554 | $result = Database::fetch_array($result); |
||
2555 | if ($result) { |
||
2556 | $sql = 'DELETE FROM track_e_access_complete WHERE id = '.$result['id']; |
||
2557 | Database::query($sql); |
||
2558 | } |
||
2559 | |||
2560 | $sql = "SELECT id FROM track_e_access_complete |
||
2561 | WHERE |
||
2562 | tool = '".TOOL_STUDENTPUBLICATION."' AND |
||
2563 | c_id = $courseId AND |
||
2564 | session_id = $sessionId AND |
||
2565 | user_id = $userId AND |
||
2566 | action_details = '$originalVirtualTime' AND |
||
2567 | action = 'add_work_end_$workId' "; |
||
2568 | $result = Database::query($sql); |
||
2569 | $result = Database::fetch_array($result); |
||
2570 | if ($result) { |
||
2571 | $sql = 'DELETE FROM track_e_access_complete WHERE id = '.$result['id']; |
||
2572 | Database::query($sql); |
||
2573 | } |
||
2574 | } |
||
2575 | |||
2576 | return false; |
||
2577 | } |
||
2578 | |||
2579 | /** |
||
2580 | * For the sake of cohesion, this function is a switch. |
||
2581 | * It's called by EventsDispatcher and fires the right function |
||
2582 | * with the right require_once. |
||
2583 | * |
||
2584 | * @deprecated |
||
2585 | * |
||
2586 | * @param string $event_name |
||
2587 | * @param array $params |
||
2588 | */ |
||
2589 | public static function event_send_mail($event_name, $params) |
||
2590 | { |
||
2591 | EventsMail::send_mail($event_name, $params); |
||
2592 | } |
||
2593 | |||
2594 | /** |
||
2595 | * Filter EventEmailTemplate Filters see the main/inc/conf/events.conf.dist.php. |
||
2596 | */ |
||
2597 | |||
2598 | /** |
||
2599 | * Basic template event message filter (to be used by other filters as default). |
||
2600 | * |
||
2601 | * @deprecated |
||
2602 | * |
||
2603 | * @param array $values (passing by reference) * |
||
2604 | * |
||
2605 | * @return bool True if everything is OK, false otherwise |
||
2606 | */ |
||
2607 | public function event_send_mail_filter_func(&$values) |
||
2608 | { |
||
2609 | return true; |
||
2610 | } |
||
2611 | |||
2612 | /** |
||
2613 | * user_registration - send_mail filter. |
||
2614 | * |
||
2615 | * @deprecated |
||
2616 | * |
||
2617 | * @param array $values (passing by reference) |
||
2618 | * |
||
2619 | * @return bool True if everything is OK, false otherwise |
||
2620 | */ |
||
2621 | public function user_registration_event_send_mail_filter_func(&$values) |
||
2622 | { |
||
2623 | $res = self::event_send_mail_filter_func($values); |
||
2624 | // proper logic for this filter |
||
2625 | return $res; |
||
2626 | } |
||
2627 | |||
2628 | /** |
||
2629 | * portal_homepage_edited - send_mail filter. |
||
2630 | * |
||
2631 | * @deprecated |
||
2632 | * |
||
2633 | * @param array $values (passing by reference) |
||
2634 | * |
||
2635 | * @return bool True if everything is OK, false otherwise |
||
2636 | */ |
||
2637 | public function portal_homepage_edited_event_send_mail_filter_func(&$values) |
||
2638 | { |
||
2639 | $res = self::event_send_mail_filter_func($values); |
||
2640 | // proper logic for this filter |
||
2641 | return $res; |
||
2642 | } |
||
2643 | |||
2644 | /** |
||
2645 | * Register the logout of the course (usually when logging out of the platform) |
||
2646 | * from the track_e_access_complete table. |
||
2647 | * |
||
2648 | * @param array $logInfo Information stored by local.inc.php |
||
2649 | * |
||
2650 | * @return bool |
||
2651 | */ |
||
2652 | public static function registerLog($logInfo) |
||
2653 | { |
||
2654 | $sessionId = api_get_session_id(); |
||
2655 | $courseId = api_get_course_int_id(); |
||
2656 | |||
2657 | if (isset($logInfo['c_id']) && !empty($logInfo['c_id'])) { |
||
2658 | $courseId = $logInfo['c_id']; |
||
2659 | } |
||
2660 | |||
2661 | if (isset($logInfo['session_id']) && !empty($logInfo['session_id'])) { |
||
2662 | $sessionId = $logInfo['session_id']; |
||
2663 | } |
||
2664 | |||
2665 | if (!Tracking::minimumTimeAvailable($sessionId, $courseId)) { |
||
2666 | return false; |
||
2667 | } |
||
2668 | |||
2669 | if (self::isSessionLogNeedToBeSave($sessionId) === false) { |
||
2670 | return false; |
||
2671 | } |
||
2672 | |||
2673 | $loginAs = (int) Session::read('login_as') === true; |
||
2674 | |||
2675 | $logInfo['user_id'] = isset($logInfo['user_id']) ? $logInfo['user_id'] : api_get_user_id(); |
||
2676 | $logInfo['date_reg'] = isset($logInfo['date_reg']) ? $logInfo['date_reg'] : api_get_utc_datetime(); |
||
2677 | $logInfo['tool'] = !empty($logInfo['tool']) ? $logInfo['tool'] : ''; |
||
2678 | $logInfo['tool_id'] = !empty($logInfo['tool_id']) ? (int) $logInfo['tool_id'] : 0; |
||
2679 | $logInfo['tool_id_detail'] = !empty($logInfo['tool_id_detail']) ? (int) $logInfo['tool_id_detail'] : 0; |
||
2680 | $logInfo['action'] = !empty($logInfo['action']) ? $logInfo['action'] : ''; |
||
2681 | $logInfo['action_details'] = !empty($logInfo['action_details']) ? $logInfo['action_details'] : ''; |
||
2682 | $logInfo['ip_user'] = api_get_real_ip(); |
||
2683 | $logInfo['user_agent'] = $_SERVER['HTTP_USER_AGENT']; |
||
2684 | $logInfo['session_id'] = $sessionId; |
||
2685 | $logInfo['c_id'] = $courseId; |
||
2686 | $logInfo['ch_sid'] = session_id(); |
||
2687 | $logInfo['login_as'] = $loginAs; |
||
2688 | $logInfo['info'] = !empty($logInfo['info']) ? $logInfo['info'] : ''; |
||
2689 | $logInfo['url'] = $_SERVER['REQUEST_URI']; |
||
2690 | $logInfo['current_id'] = isset($logInfo['current_id']) ? $logInfo['current_id'] : Session::read('last_id', 0); |
||
2691 | |||
2692 | $id = Database::insert('track_e_access_complete', $logInfo); |
||
2693 | if ($id && empty($logInfo['current_id'])) { |
||
2694 | Session::write('last_id', $id); |
||
2695 | } |
||
2696 | |||
2697 | return true; |
||
2698 | } |
||
2699 | |||
2700 | public static function getAttemptQuestionDuration($exeId, $questionId) |
||
2724 | } |
||
2725 | |||
2726 | public static function logSubscribedUserInCourse(int $subscribedId, int $courseId) |
||
2727 | { |
||
2728 | $dateTime = api_get_utc_datetime(); |
||
2729 | $registrantId = api_get_user_id(); |
||
2730 | |||
2747 | ); |
||
2748 | } |
||
2749 | |||
2750 | public static function logUserSubscribedInCourseSession(int $subscribedId, int $courseId, int $sessionId) |
||
2751 | { |
||
2752 | $dateTime = api_get_utc_datetime(); |
||
2753 | $registrantId = api_get_user_id(); |
||
2754 | |||
2755 | self::addEvent( |
||
2756 | LOG_SESSION_ADD_USER_COURSE, |
||
2757 | LOG_USER_ID, |
||
2781 | ); |
||
2782 | } |
||
2783 | } |
||
2784 |