diff --git a/public/main/exercise/recalculate_all.php b/public/main/exercise/recalculate_all.php index 89f5e0a63a..adcc5f11e7 100644 --- a/public/main/exercise/recalculate_all.php +++ b/public/main/exercise/recalculate_all.php @@ -26,7 +26,7 @@ if (!$is_allowedToEdit) { $result = ExerciseLib::get_exam_results_data( 0, 0, - 1, + null, 'asc', $exerciseId, '', diff --git a/public/main/lp/learnpath.class.php b/public/main/lp/learnpath.class.php index 1abc7a0e42..b829935ab0 100644 --- a/public/main/lp/learnpath.class.php +++ b/public/main/lp/learnpath.class.php @@ -4,6 +4,7 @@ use Chamilo\CoreBundle\Entity\Course; use Chamilo\CoreBundle\Entity\ResourceLink; +use Chamilo\CoreBundle\Entity\TrackEExercise; use Chamilo\CoreBundle\Entity\User; use Chamilo\CoreBundle\Entity\Session as SessionEntity; use Chamilo\CoreBundle\ServiceHelper\ThemeHelper; @@ -8796,4 +8797,65 @@ class learnpath return $document ? $repo->getResourceFileContent($document) : ''; } + + /** + * Recalculates the results for all exercises associated with the learning path (LP) for the given user. + */ + public function recalculateResultsForLp(int $userId): void + { + $em = Database::getManager(); + $lpItemRepo = $em->getRepository(CLpItem::class); + $lpItems = $lpItemRepo->findBy(['lp' => $this->lp_id]); + + if (empty($lpItems)) { + Display::addFlash(Display::return_message(get_lang('No items found'), 'error')); + return; + } + + $lpItemIds = array_map(fn($item) => $item->getIid(), $lpItems); + $lpItemViewRepo = $em->getRepository(CLpItemView::class); + $lpItemViews = $lpItemViewRepo->createQueryBuilder('v') + ->where('v.item IN (:lpItemIds)') + ->setParameter('lpItemIds', $lpItemIds) + ->getQuery() + ->getResult(); + + if (empty($lpItemViews)) { + Display::addFlash(Display::return_message(get_lang('No item views found'), 'error')); + return; + } + + $lpViewIds = array_map(fn($view) => $view->getIid(), $lpItemViews); + $trackEExerciseRepo = $em->getRepository(TrackEExercise::class); + $trackExercises = $trackEExerciseRepo->createQueryBuilder('te') + ->where('te.origLpId = :lpId') + ->andWhere('te.origLpItemId IN (:lpItemIds)') + ->andWhere('te.origLpItemViewId IN (:lpViewIds)') + ->andWhere('te.user = :userId') + ->setParameter('lpId', $this->lp_id) + ->setParameter('lpItemIds', $lpItemIds) + ->setParameter('lpViewIds', $lpViewIds) + ->setParameter('userId', $userId) + ->getQuery() + ->getResult(); + + if (empty($trackExercises)) { + Display::addFlash(Display::return_message(get_lang('No exercise attempts found'), 'error')); + return; + } + + foreach ($trackExercises as $trackExercise) { + $exeId = $trackExercise->getExeId(); + $exerciseId = $trackExercise->getQuiz()->getIid(); + $courseId = $trackExercise->getCourse()->getId(); + + $result = ExerciseLib::recalculateResult($exeId, $userId, $exerciseId, $courseId); + + if ($result) { + Display::addFlash(Display::return_message(get_lang('Results recalculated'), 'success')); + } else { + Display::addFlash(Display::return_message(get_lang('Error recalculating results'), 'error')); + } + } + } } diff --git a/public/main/lp/lp_controller.php b/public/main/lp/lp_controller.php index a6b3a0be7e..c1e80fa683 100644 --- a/public/main/lp/lp_controller.php +++ b/public/main/lp/lp_controller.php @@ -203,6 +203,26 @@ if (isset($_POST['title'])) { $redirectTo = ''; switch ($action) { + case 'recalculate': + if (!isset($oLP) || !$lp_found) { + Display::addFlash(Display::return_message(get_lang('NoLpFound'), 'error')); + header("Location: $listUrl"); + exit; + } + + $userId = isset($_GET['user_id']) ? (int) $_GET['user_id'] : 0; + + if (0 === $userId) { + Display::addFlash(Display::return_message(get_lang('NoUserIdProvided'), 'error')); + header("Location: $listUrl"); + exit; + } + + $oLP->recalculateResultsForLp($userId); + + $url = api_get_self().'?action=report&lp_id='.$lpId.'&'.api_get_cidreq(); + header("Location: $url"); + exit; case 'author_view': $teachers = []; $field = new ExtraField('user'); diff --git a/public/main/lp/lp_report.php b/public/main/lp/lp_report.php index d25885782c..df2e518403 100644 --- a/public/main/lp/lp_report.php +++ b/public/main/lp/lp_report.php @@ -359,6 +359,12 @@ if (!empty($users)) { ['data-id' => $userId, 'data-username' => $userInfo['username'], 'class' => 'delete_attempt'] ); + $actions .= Display::url( + Display::getMdiIcon('file-document-refresh', 'ch-tool-icon', null, 32, get_lang('Recalculate result')), + api_get_path(WEB_CODE_PATH) . 'lp/lp_controller.php?'.api_get_cidreq().'&action=recalculate&user_id='.$userId.'&lp_id='.$lpId, + ['title' => get_lang('Recalculate result')] + ); + $row[] = $actions; $row['username'] = $userInfo['username']; $userList[] = $row; diff --git a/src/CourseBundle/Entity/CLpView.php b/src/CourseBundle/Entity/CLpView.php index af10a20fa1..83b4b90d65 100644 --- a/src/CourseBundle/Entity/CLpView.php +++ b/src/CourseBundle/Entity/CLpView.php @@ -51,6 +51,11 @@ class CLpView #[ORM\Column(name: 'progress', type: 'integer', nullable: true)] protected ?int $progress = null; + public function getIid(): ?int + { + return $this->iid; + } + public function setViewCount(int $viewCount): self { $this->viewCount = $viewCount;