19 declare(strict_types=1);
40 #region Constants / Config 124 private \ILIAS\ResourceStorage\Services
$irss;
132 $this->
lng = $DIC[
'lng'];
133 $this->db = $DIC[
'ilDB'];
134 $this->
ctrl = $DIC[
'ilCtrl'];
135 $this->
user = $DIC[
'ilUser'];
136 $this->
tabs = $DIC[
'ilTabs'];
137 $this->
toolbar = $DIC[
'ilToolbar'];
138 $this->tpl = $DIC[
'tpl'];
139 $this->ui_factory = $DIC[
'ui.factory'];
140 $this->ui_renderer = $DIC[
'ui.renderer'];
141 $this->
access = $DIC[
'ilAccess'];
142 $this->testrequest = $DIC->test()->internal()->request();
143 $this->
http = $DIC->http();
145 $this->irss = $DIC->resourceStorage();
147 $ilias = $DIC[
'ilias'];
151 $this->external_directory_path = $ilias->ini_ilias->readVariable(
'clients',
'datadir');
152 $this->client_id = $ilias->client_id;
158 $this->participantData = null;
194 . self::DIR_SEP . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
195 if (!is_dir($pass_question_directory)) {
196 mkdir($pass_question_directory, 0777,
true);
199 copy($file_path, $pass_question_directory . self::DIR_SEP . $original_filename);
202 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
203 . $pass_question_directory . self::DIR_SEP . $original_filename
221 $new_path = $this->
getPassDataDirectory($active_fi, $pass) . self::DIR_SEP . $original_filename;
222 copy($file_path, $new_path);
223 $this->
logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
236 $best_solution_path = $this->
getTestArchive() . self::DIR_SEP . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
237 if (!is_dir($best_solution_path)) {
238 mkdir($best_solution_path, 0777,
true);
241 $this->html_generator->generateHTML(
243 $best_solution_path . self::DIR_SEP . self::HTML_BEST_SOLUTION_FILENAME
247 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
248 . $best_solution_path . self::DIR_SEP . self::HTML_BEST_SOLUTION_FILENAME
252 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $best_solution_path
262 $questions = $tst_obj->getQuestionsOfPass($active_fi, $pass);
263 foreach ($questions as $question) {
264 $question = $tst_obj->getQuestionDataset($question[
'question_fi']);
265 if ($question->type_tag ===
'assFileUpload') {
270 $archive_folder = $pass_material_directory . self::DIR_SEP . $question->question_id . self::DIR_SEP;
271 if (!file_exists($archive_folder)) {
272 mkdir($archive_folder, 0777,
true);
275 $local_folder =
CLIENT_WEB_DIR .
'/assessment/tst_' . $tst_obj->test_id . self::DIR_SEP . $active_fi . self::DIR_SEP . $question->question_id .
'/files/';
276 if (file_exists($local_folder)) {
277 $folder_content = scandir($local_folder);
278 $folder_content = array_diff($folder_content, array(
'.',
'..'));
279 foreach ($folder_content as $file_name) {
280 if (preg_match(
'/file_(\d+)_(\d+)_(\d+)/', $file_name, $matches)){
281 if ($active_fi == intval($matches[1]) && $pass == $matches[2]){
282 $local_file= $local_folder . $file_name;
283 $target_destination = $archive_folder . $file_name;
284 copy($local_file, $target_destination);
285 $this->
logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $target_destination);
291 $resource_id = $tst_obj->getTextAnswer($active_fi, $question->question_id, $pass);
292 if ($resource_id ==
''){
295 $irss_unique_id = $this->irss->manage()->find($resource_id);
296 if ($irss_unique_id != null){
297 $resource = $this->irss->manage()->getResource($irss_unique_id);
298 $information = $resource->getCurrentRevision()->getInformation();
299 $stream = $this->irss->consume()->stream($irss_unique_id);
301 $file_stream = fopen($stream->getStream()->getMetadata(
'uri'),
'r');
302 $file_content = stream_get_contents($file_stream);
303 fclose($file_stream);
304 $target_destination = $archive_folder . $information->getTitle();
305 file_put_contents($target_destination, $file_content);
322 $best_solution_path = $this->
getTestArchive() . self::DIR_SEP . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
323 if (!is_dir($best_solution_path)) {
324 mkdir($best_solution_path, 0777,
true);
327 $materials_path = $best_solution_path . self::DIR_SEP . self::TEST_MATERIALS_PATH_COMPONENT;
328 if (!is_dir($materials_path)) {
329 mkdir($materials_path, 0777,
true);
332 $question_materials_path = $materials_path . self::DIR_SEP . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
333 if (!is_dir($question_materials_path)) {
334 mkdir($question_materials_path, 0777,
true);
337 copy($file_path, $question_materials_path . self::DIR_SEP . $orginial_filename);
340 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
341 . $question_materials_path . self::DIR_SEP . $orginial_filename
358 $new_path = $this->
getPassDataDirectory($active_fi, $pass) . self::DIR_SEP . self::TEST_RESULT_FILENAME;
359 copy($pdf_path, $new_path);
360 $this->
logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
394 $test_archive_directory = $this->external_directory_path . self::DIR_SEP . $this->client_id . self::DIR_SEP .
'tst_data' 396 return $test_archive_directory;
421 $query =
'SELECT * FROM ass_log WHERE obj_fi = ' . $this->db->quote($this->test_obj_id,
'integer');
422 $result = $this->db->query($query);
426 while ($row = $this->db->fetchAssoc($result)) {
427 $outfile_lines .=
"\r\n" . implode(
"\t", $row);
429 file_put_contents($this->
getTestArchive() . self::DIR_SEP . self::TEST_LOG_FILENAME, $outfile_lines);
432 $test =
new ilObjTest($this->test_obj_id,
false);
433 if ($this->test_ref_id !== null) {
434 $test->setRefId($this->test_ref_id);
452 $gui->setTestObj($test);
455 $gui->setObjectiveParent($objectiveOrientedContainer);
456 $array_of_actives = array();
457 $participants = $test->getParticipants();
459 foreach ($participants as
$key => $value) {
460 $array_of_actives[] =
$key;
462 $output_template = $gui->createUserResults(
true,
false,
true, $array_of_actives);
465 $this->html_generator->generateHTML($output_template->get(),
$filename);
499 return $this->external_directory_path . self::DIR_SEP . $this->client_id . self::DIR_SEP .
'tst_data' 500 . self::DIR_SEP . self::EXPORT_DIRECTORY . self::DIR_SEP .
'tst_' .
$this->test_obj_id;
514 $zip_output_filename =
'test_archive_obj_' . $this->test_obj_id .
'_' . time() .
'_.zip';
522 #region PassDataDirectory 558 foreach ($this->archive_data_index as $data_index_entry) {
559 if ($data_index_entry != null && $data_index_entry[
'identifier'] == $active_fi .
'|' . $pass) {
560 array_shift($data_index_entry);
561 return $this->
getTestArchive() . self::DIR_SEP . implode(self::DIR_SEP, $data_index_entry);
580 if ($pass_data_dir !== null) {
581 return $pass_data_dir;
584 $test_obj =
new ilObjTest($this->test_obj_id,
false);
585 if ($test_obj->getAnonymity()) {
586 $firstname =
'anonym';
588 $matriculation =
'0';
592 $firstname = $usr_data[
'firstname'];
593 $lastname = $usr_data[
'lastname'];
594 $matriculation = $usr_data[
'matriculation'];
597 $firstname = $this->
user->getFirstname();
598 $lastname = $this->
user->getLastname();
599 $matriculation = $this->
user->getMatriculation();
635 #region PassMaterialsDirectory 687 mkdir($material_directory, 0777,
true);
688 return $material_directory;
702 return $pass_data_directory . self::DIR_SEP . self::PASS_MATERIALS_PATH_COMPONENT;
734 $data_index_file = $this->
getTestArchive() . self::DIR_SEP . self::DATA_INDEX_FILENAME;
739 if (@file_exists($data_index_file)) {
740 $lines = explode(
"\n", file_get_contents($data_index_file));
741 foreach ($lines as $line) {
742 if (strlen($line) === 0) {
745 $line_items = explode(
'|', $line);
747 $line_data[
'identifier'] = $line_items[0] .
'|' . $line_items[1];
748 $line_data[
'yyyy'] = $line_items[2];
749 $line_data[
'mm'] = $line_items[3];
750 $line_data[
'dd'] = $line_items[4];
751 $line_data[
'directory'] = $line_items[5];
752 $contents[] = $line_data;
772 $line = $this->
determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation);
774 $this->archive_data_index[] = $line;
775 $output_contents =
'';
777 foreach ($this->archive_data_index as $line_data) {
778 if ($line_data[
'identifier'] ==
"|") {
781 $output_contents .= implode(
'|', $line_data) .
"\n";
784 file_put_contents($this->
getTestArchive() . self::DIR_SEP . self::DATA_INDEX_FILENAME, $output_contents);
801 protected function determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation): array
803 $date = date_create_from_format(
'Y-m-d\TH:i:sP', $date);
805 throw new Exception(
'Invalid date format. Expected ISO 8601 format.');
809 'identifier' => $active_fi .
'|' . $pass,
810 'yyyy' => date_format($date,
'Y'),
811 'mm' => date_format($date,
'm'),
812 'dd' => date_format($date,
'd'),
813 'directory' => $active_fi .
'_' . $pass .
'_' . $user_firstname .
'_' . $user_lastname .
'_' . $matriculation
827 $archive = $this->
getTestArchive() . self::DIR_SEP . self::ARCHIVE_LOG;
828 if (file_exists($archive)) {
829 $content = file_get_contents($archive) .
"\n" .
$message;
834 file_put_contents($archive, $content);
850 if ($handle = opendir($directory)) {
851 while (($file = readdir($handle)) !==
false) {
852 if (!in_array($file, array(
'.',
'..' )) && !is_dir($directory . $file)) {
853 if ($pattern && strpos($file, $pattern) === 0) {
getPassDataDirectory($active_fi, $pass)
Returns the pass data directory.
Interface GlobalHttpState.
determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation)
Determines the pass data path.
createArchiveForTest()
Creates the directory for the test archive.
const LOG_DTSGROUP_FORMAT
ilParticipantsTestResultsGUI: ilTestEvaluationGUI ilParticipantsTestResultsGUI: ilAssQuestionPageGUI...
const HTML_BEST_SOLUTION_FILENAME
createZipExportDirectory()
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
const TEST_RESULT_FILENAME
setMatriculation(string $a_str)
InternalRequestService $testrequest
createPassDataDirectory($active_fi, $pass)
Creates pass data directory.
countFilesInDirectory($directory, $pattern=null)
Returns the count of files in a directory, eventually matching the given, optional, pattern.
ensureZipExportDirectoryExists()
const TEST_OVERVIEW_HTML_POSTFIX
RefineryFactory $refinery
const DATA_INDEX_FILENAME
handInParticipantQuestionMaterial($active_fi, $pass, $question_fi, $original_filename, $file_path)
Hands in a particpants question material, such as an upload or other binary content.
const LOG_DELETION_STRING
getPassMaterialsDirectory($active_fi, $pass)
Returns the pass materials directory.
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
const PASS_MATERIALS_PATH_COMPONENT
const HTML_SUBMISSION_FILENAME
ilGlobalTemplateInterface $tpl
compressTestArchive()
Generate the test archive for download.
readArchiveDataIndex()
Reads the archive data index.
const TEST_OVERVIEW_HTML_FILENAME
static http()
Fetches the global http state from ILIAS.
const QUESTION_PATH_COMPONENT_PREFIX
getZipExportDirectory()
Return the export directory, where zips are placed.
buildPassDataDirectory($active_fi, $pass)
appendToArchiveDataIndex($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation)
Appends a line to the archive data index.
ensurePassDataDirectoryIsAvailable($active_fi, $pass)
Ensures the availability of the participant data directory.
handInBestSolutionQuestionMaterial($question_fi, $orginial_filename, $file_path)
Hands in a file related to a question in context of the best solution.
const LOG_ADDITION_STRING
const LOG_CREATION_STRING
hasZipExportDirectory()
Returns if the export directory for zips exists.
handInParticipantUploadedResults($active_fi, $pass, $tst_obj)
hasTestArchive()
Returns if the archive directory structure for the test the object is created for exists...
Class that handles PDF generation for test and assessment.
setLastname(string $a_str)
getTestArchive()
Returns the (theoretical) path to the archive directory of the test, this object is created for...
ILIAS ResourceStorage Services $irss
hasPassDataDirectory($active_fi, $pass)
Checks if the directory for pass data is available.
hasPassMaterialsDirectory($active_fi, $pass)
Returns if the pass materials directory exists for a given pass.
createPassMaterialsDirectory($active_fi, $pass)
Creates pass materials directory.
static zip(string $a_dir, string $a_file, bool $compress_content=false)
const TEST_BEST_SOLUTION_PATH_COMPONENT
ensurePassMaterialsDirectoryIsAvailable($active_fi, $pass)
Ensures the availability of the pass materials directory.
ensureTestArchiveIsAvailable()
Ensures the availability of the test archive directory.
handInTestBestSolution($best_solution)
Hands in the best solution for a test.
handInParticipantMisc($active_fi, $pass, $original_filename, $file_path)
Hands in a participants file, which is relevant for archiving but an unspecified type.
setFirstname(string $a_str)
const TEST_MATERIALS_PATH_COMPONENT
ilTestHTMLGenerator $html_generator
setParticipantData($participantData)
logArchivingProcess($message)
Logs to the archive log.
updateTestArchive()
Replaces the test-log with the current one.
handInTestResult($active_fi, $pass, $pdf_path)
Hands in an individual test result for a pass.