diff --git a/plugin/exercisefocused/src/Traits/ReportingFilterTrait.php b/plugin/exercisefocused/src/Traits/ReportingFilterTrait.php index 9c72d67616c..648a6708937 100644 --- a/plugin/exercisefocused/src/Traits/ReportingFilterTrait.php +++ b/plugin/exercisefocused/src/Traits/ReportingFilterTrait.php @@ -12,6 +12,7 @@ use Display; use Doctrine\ORM\Query\Expr\Join; use Exception; +use ExerciseMonitoringPlugin; use ExtraField; use ExtraFieldValue; use FormValidator; @@ -192,9 +193,13 @@ protected function formatResults(array $queryResults): array protected function createTable(array $tableData): HTML_Table { + $monitoringPluginEnabled = ExerciseMonitoringPlugin::create()->isEnabled(true); + $detailIcon = Display::return_icon('forum_listview.png', get_lang('Detail')); + $webcamIcon = Display::return_icon('webcam.png', $this->plugin->get_lang('MonitoringDetail')); $urlDetail = api_get_path(WEB_PLUGIN_PATH).'exercisefocused/pages/detail.php?'.api_get_cidreq().'&'; + $monitoringDetail = api_get_path(WEB_PLUGIN_PATH).'exercisemonitoring/pages/detail.php?'.api_get_cidreq().'&'; $table = new HTML_Table(['class' => 'table table-hover table-striped data_table']); $table->setHeaderContents(0, 0, get_lang('Username')); @@ -219,6 +224,18 @@ protected function createTable(array $tableData): HTML_Table ] ); + if ($monitoringPluginEnabled) { + $url .= Display::url( + $webcamIcon, + $monitoringDetail.http_build_query(['id' => $result['id']]), + [ + 'class' => 'ajax', + 'data-title' => get_lang('MonitoringDetail'), + 'data-size' => 'lg', + ] + ); + } + $table->setCellContents($row, 0, $result['username']); $table->setCellContents($row, 1, $result['user_fullname']); $table->setCellContents($row, 2, $result['quiz_title']); diff --git a/plugin/exercisemonitoring/pages/detail.php b/plugin/exercisemonitoring/pages/detail.php new file mode 100644 index 00000000000..33b471f94c7 --- /dev/null +++ b/plugin/exercisemonitoring/pages/detail.php @@ -0,0 +1,32 @@ +getRepository(Log::class); + +$detailController = new DetailController( + ExerciseMonitoringPlugin::create(), + HttpRequest::createFromGlobals(), + $em, + $logRepository +); + +try { + $response = $detailController(); +} catch (Exception $e) { + $response = HttpResponse::create('', HttpResponse::HTTP_FORBIDDEN); +} + +$response->send(); diff --git a/plugin/exercisemonitoring/src/Controller/DetailController.php b/plugin/exercisemonitoring/src/Controller/DetailController.php new file mode 100644 index 00000000000..616206b5844 --- /dev/null +++ b/plugin/exercisemonitoring/src/Controller/DetailController.php @@ -0,0 +1,161 @@ +plugin = $plugin; + $this->request = $request; + $this->em = $em; + $this->logRepository = $logRepository; + } + + /** + * @throws Exception + */ + public function __invoke(): HttpResponse + { + if (!$this->plugin->isEnabled(true)) { + throw new Exception(); + } + + $trackExe = $this->em->find( + TrackEExercises::class, + $this->request->query->getInt('id') + ); + + if (!$trackExe) { + throw new Exception(); + } + + $exercise = $this->em->find(CQuiz::class, $trackExe->getExeExoId()); + $user = api_get_user_entity($trackExe->getExeUserId()); + + $objExercise = new Exercise(); + $objExercise->read($trackExe->getExeExoId()); + + $qb = $this->logRepository->createQueryBuilder('l'); + $qb + ->select(['l.imageFilename', 'l.createdAt']); + + if (ONE_PER_PAGE == $objExercise->selectType()) { + $qb + ->addSelect(['qq.question']) + ->innerJoin(CQuizQuestion::class, 'qq', Join::WITH, 'l.level = qq.iid'); + } + + $logs = $qb + ->andWhere( + $qb->expr()->eq('l.exe', $trackExe->getExeId()) + ) + ->addOrderBy('l.createdAt') + ->getQuery() + ->getResult(); + + $content = $this->generateHeader($objExercise, $user, $trackExe) + .'
' + .$this->generateSnapshotList($logs, $trackExe->getExeUserId()); + + return HttpResponse::create($content); + } + + private function generateHeader(Exercise $objExercise, User $student, TrackEExercises $trackExe): string + { + $startDate = api_get_local_time($trackExe->getStartDate(), null, null, true, true, true); + $endDate = api_get_local_time($trackExe->getExeDate(), null, null, true, true, true); + + return Display::page_subheader2($objExercise->selectTitle()) + .Display::tag('p', $student->getCompleteNameWithUsername(), ['class' => 'lead']) + .Display::tag( + 'p', + sprintf(get_lang('QuizRemindStartDate'), $startDate) + .sprintf(get_lang('QuizRemindEndDate'), $endDate) + .sprintf(get_lang('QuizRemindDuration'), api_format_time($trackExe->getExeDuration())) + ); + } + + /** + * @param array $logs + * @param int $userId + * + * @return string + */ + private function generateSnapshotList(array $logs, int $userId): string + { + $pluginDirName = api_get_path(WEB_UPLOAD_PATH).'plugins/exercisemonitoring'; + + $html = ''; + + foreach ($logs as $log) { + $userDirName = $pluginDirName.'/'.$userId; + + $date = api_get_local_time($log['createdAt'], null, null, true, true, true); + + $html .= '
'; + $html .= '
'; + $html .= Display::img( + $userDirName.'/'.$log['imageFilename'], + $date + ); + $html .= '
'; + $html .= Display::tag('p', $date, ['class' => 'text-center']); + + if (!empty($log['question'])) { + $html .= Display::tag('div', $log['question'], ['class' => 'text-center']); + } + + $html .= '
'; + $html .= '
'; + $html .= '
'; + } + + return '
'.$html.'
'; + } +} diff --git a/plugin/exercisemonitoring/src/Controller/ExerciseSubmitController.php b/plugin/exercisemonitoring/src/Controller/ExerciseSubmitController.php index f195412950c..09c036fbdec 100644 --- a/plugin/exercisemonitoring/src/Controller/ExerciseSubmitController.php +++ b/plugin/exercisemonitoring/src/Controller/ExerciseSubmitController.php @@ -37,10 +37,12 @@ public function __invoke(): HttpResponse $existingExeId = (int) ChamiloSession::read('exe_id'); $levelId = $this->request->request->getInt('level_id'); - $exercise = $this->em->find( - CQuiz::class, - $this->request->request->getInt('exercise_id') - ); + $exerciseId = $this->request->request->getInt('exercise_id'); + + $exercise = $this->em->find(CQuiz::class, $exerciseId); + + $objExercise = new Exercise(); + $objExercise->read($exerciseId); $trackingExercise = $this->em->find(TrackEExercises::class, $existingExeId); @@ -54,7 +56,7 @@ public function __invoke(): HttpResponse $imgSubmit->move($userDirName, $newFilename); } - if (ONE_PER_PAGE === $exercise->getType()) { + if (ONE_PER_PAGE == $objExercise->selectType()) { $question = $this->em->find(CQuizQuestion::class, $levelId); $level = $question->getIid(); }