ILIAS  release_8 Revision v8.24
class.ilTestArchiver.php
Go to the documentation of this file.
1<?php
2
31{
32 #region Constants / Config
33
34 public const DIR_SEP = '/';
35
36 public const HTML_SUBMISSION_FILENAME = 'test_submission.html';
37 public const PDF_SUBMISSION_FILENAME = 'test_submission.pdf';
38 public const PASS_MATERIALS_PATH_COMPONENT = 'materials';
39 public const QUESTION_PATH_COMPONENT_PREFIX = 'q_';
40
41 public const TEST_BEST_SOLUTION_PATH_COMPONENT = 'best_solution';
42 public const HTML_BEST_SOLUTION_FILENAME = 'best_solution.html';
43 public const PDF_BEST_SOLUTION_FILENAME = 'best_solution.pdf';
44 public const TEST_MATERIALS_PATH_COMPONENT = 'materials';
45
46 protected const TEST_RESULT_FILENAME = 'test_result.pdf';
47
48 public const TEST_OVERVIEW_PDF_FILENAME = 'results_overview_html_v';
49 public const TEST_OVERVIEW_PDF_POSTFIX = '.pdf';
50
51 public const TEST_OVERVIEW_HTML_FILENAME = 'results_overview_pdf_v';
52 public const TEST_OVERVIEW_HTML_POSTFIX = '.html';
53
54 public const LOG_DTSGROUP_FORMAT = 'D M j G:i:s T Y';
55 public const LOG_ADDITION_STRING = ' Adding ';
56 public const LOG_CREATION_STRING = ' Creating ';
57 public const LOG_UPDATE_STRING = ' Updating ';
58 public const LOG_DELETION_STRING = ' Deleting ';
59
60 public const TEST_LOG_FILENAME = 'test.log';
61 public const DATA_INDEX_FILENAME = 'data_index.csv';
62 public const ARCHIVE_LOG = 'archive.log';
63
64 public const EXPORT_DIRECTORY = 'archive_exports';
65
66 #endregion
67
68 /*
69 * Test-Archive Schema:
70 *
71 * <external directory>/<client>/tst_data/archive/tst_<obj_id>/
72 * - archive_data_index.dat
73 * - archive_log.log
74 *
75 * - test_log.log
76 *
77 * - test_results_v<n>.pdf
78 * - test_results_v<n>.csv
79 *
80 * -> best_solution/
81 * best_solution_v<n>.pdf
82 * -> /materials/q_<question_fi>/<n>_<filename>
83 *
84 * -> <year>/<month>/<day>/<ActiveFi>_<Pass>[_<Lastname>][_<Firstname>][_<Matriculation>]/
85 * -> test_submission.pdf
86 * -> test_submission.html
87 * -> test_submission.sig (et al)
88 * -> test_result_v<n>.pdf
89 * -> /materials_v<n>/<question_fi>/<n>_<filename>
90 */
91
92 #region Properties
93
95 protected $client_id;
96 protected $test_obj_id;
97 protected $test_ref_id;
99
101
106
107 #endregion
108
114 public function __construct($test_obj_id, $test_ref_id = null)
115 {
117 global $DIC;
118 $ilias = $DIC['ilias'];
119 $this->external_directory_path = $ilias->ini_ilias->readVariable('clients', 'datadir');
120 $this->client_id = $ilias->client_id;
121 $this->test_obj_id = $test_obj_id;
122 $this->test_ref_id = $test_ref_id;
123 $this->ilDB = $ilias->db;
124
125 $this->archive_data_index = $this->readArchiveDataIndex();
126
127 $this->participantData = null;
128 }
129
134 {
136 }
137
142 {
143 $this->participantData = $participantData;
144 }
145
146 #region API methods
147
160 public function handInParticipantSubmission($active_fi, $pass, $pdf_path, $html_string)
161 {
163 $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
164
165 $pdf_new_path = $this->getPassDataDirectory($active_fi, $pass) . self::DIR_SEP
167 copy($pdf_path, $pdf_new_path);
168 # /home/mbecker/public_html/ilias/trunk-primary/extern/default/tst_data/archive/tst_350/2013/09/19/80_1_root_user_/test_submission.pdf
169 $html_new_path = $this->getPassDataDirectory($active_fi, $pass) . self::DIR_SEP
171 file_put_contents($html_new_path, $html_string);
172
173 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $pdf_new_path);
174 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $html_new_path);
175 }
176
186 public function handInParticipantQuestionMaterial($active_fi, $pass, $question_fi, $original_filename, $file_path)
187 {
189 $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
190
191 $pass_question_directory = $this->getPassDataDirectory($active_fi, $pass)
192 . self::DIR_SEP . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
193 if (!is_dir($pass_question_directory)) {
194 mkdir($pass_question_directory, 0777, true);
195 }
196
197 copy($file_path, $pass_question_directory . self::DIR_SEP . $original_filename);
198
199 $this->logArchivingProcess(
200 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
201 . $pass_question_directory . self::DIR_SEP . $original_filename
202 );
203 }
204
210 public function handInParticipantUploadedResults($active_fi, $pass, $tst_obj)
211 {
212 $questions = $tst_obj->getQuestionsOfPass($active_fi, $pass);
213 foreach ($questions as $question) {
214 $question = $tst_obj->getQuestionDataset($question['question_fi']);
215 if ($question->type_tag === 'assFileUpload') {
216 $local_folder = CLIENT_WEB_DIR . '/assessment/tst_' . $tst_obj->test_id . self::DIR_SEP . $active_fi . self::DIR_SEP . $question->question_id . '/files/';
217 if (!file_exists($local_folder)) {
218 continue; // no file submissions
219 }
221 $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
222 $folder_content = scandir($local_folder);
223 $folder_content = array_diff($folder_content, array('.', '..'));
224 $this->ensurePassMaterialsDirectoryIsAvailable($active_fi, $pass);
225 $pass_material_directory = $this->getPassMaterialsDirectory($active_fi, $pass);
226 $archive_folder = $pass_material_directory . self::DIR_SEP . $question->question_id . self::DIR_SEP;
227 if (!file_exists($archive_folder)) {
228 mkdir($archive_folder, 0777, true);
229 }
230 foreach ($folder_content as $file_name) {
231 if (preg_match('/file_(\d+)_(\d+)_(\d+)/', $file_name, $matches)) {
232 if ($active_fi == intval($matches[1]) && $pass == $matches[2]) {
233
234 $local_file = $local_folder . $file_name;
235 $target_destination = $archive_folder . $file_name;
236 copy($local_file, $target_destination);
237 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $target_destination);
238 }
239 }
240 }
241 }
242 }
243 }
244
255 public function handInParticipantMisc($active_fi, $pass, $original_filename, $file_path)
256 {
258 $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
259 $new_path = $this->getPassDataDirectory($active_fi, $pass) . self::DIR_SEP . $original_filename;
260 copy($file_path, $new_path);
261 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
262 }
263
270 public function handInTestBestSolution($html_string, $pdf_path)
271 {
273
274 $best_solution_path = $this->getTestArchive() . self::DIR_SEP . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
275 if (!is_dir($best_solution_path)) {
276 mkdir($best_solution_path, 0777, true);
277 }
278
279 file_put_contents($best_solution_path . self::DIR_SEP . self::HTML_BEST_SOLUTION_FILENAME, $html_string);
280
281 copy($pdf_path, $best_solution_path . self::DIR_SEP . self::PDF_BEST_SOLUTION_FILENAME);
282
283 $this->logArchivingProcess(
284 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
285 . $best_solution_path . self::DIR_SEP . self::HTML_BEST_SOLUTION_FILENAME
286 );
287
288 $this->logArchivingProcess(
289 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
290 . $best_solution_path . self::DIR_SEP . self::PDF_BEST_SOLUTION_FILENAME
291 );
292 }
293
301 public function handInBestSolutionQuestionMaterial($question_fi, $orginial_filename, $file_path)
302 {
304
305 $best_solution_path = $this->getTestArchive() . self::DIR_SEP . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
306 if (!is_dir($best_solution_path)) {
307 mkdir($best_solution_path, 0777, true);
308 }
309
310 $materials_path = $best_solution_path . self::DIR_SEP . self::TEST_MATERIALS_PATH_COMPONENT;
311 if (!is_dir($materials_path)) {
312 mkdir($materials_path, 0777, true);
313 }
314
315 $question_materials_path = $materials_path . self::DIR_SEP . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
316 if (!is_dir($question_materials_path)) {
317 mkdir($question_materials_path, 0777, true);
318 }
319
320 copy($file_path, $question_materials_path . self::DIR_SEP . $orginial_filename);
321
322 $this->logArchivingProcess(
323 date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
324 . $question_materials_path . self::DIR_SEP . $orginial_filename
325 );
326 }
327
337 public function handInTestResult($active_fi, $pass, $pdf_path)
338 {
340 $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
341 $new_path = $this->getPassDataDirectory($active_fi, $pass) . self::DIR_SEP . self::TEST_RESULT_FILENAME;
342 copy($pdf_path, $new_path);
343 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
344 }
345
352 public function handInTestResultsOverview($html_string, $pdf_path)
353 {
355 $new_pdf_path = $this->getTestArchive() . self::DIR_SEP
356 . self::TEST_OVERVIEW_PDF_FILENAME
357 . $this->countFilesInDirectory($this->getTestArchive(), self::TEST_OVERVIEW_PDF_FILENAME) . self::TEST_OVERVIEW_PDF_POSTFIX;
358 copy($pdf_path, $new_pdf_path);
359 $html_path = $this->getTestArchive() . self::DIR_SEP . self::TEST_OVERVIEW_HTML_FILENAME
360 . $this->countFilesInDirectory($this->getTestArchive(), self::TEST_OVERVIEW_HTML_FILENAME) . self::TEST_OVERVIEW_HTML_POSTFIX;
361 file_put_contents($html_path, $html_string);
362
363 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_pdf_path);
364 $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $html_path);
365 }
366
367 #endregion
368
369 #region TestArchive
370 // The TestArchive lives here: <external directory>/<client>/tst_data/archive/tst_<obj_id>/
371
377 protected function hasTestArchive(): bool
378 {
379 return is_dir($this->getTestArchive());
380 }
381
385 protected function createArchiveForTest()
386 {
388 //mkdir( $this->getTestArchive(), 0777, true );
389 }
390
396 protected function getTestArchive(): string
397 {
398 $test_archive_directory = $this->external_directory_path . self::DIR_SEP . $this->client_id . self::DIR_SEP . 'tst_data'
399 . self::DIR_SEP . 'archive' . self::DIR_SEP . 'tst_' . $this->test_obj_id;
400 return $test_archive_directory;
401 }
402
410 protected function ensureTestArchiveIsAvailable()
411 {
412 if (!$this->hasTestArchive()) {
413 $this->createArchiveForTest();
414 }
415 return;
416 }
417
423 public function updateTestArchive()
424 {
425 $query = 'SELECT * FROM ass_log WHERE obj_fi = ' . $this->ilDB->quote($this->test_obj_id, 'integer');
426 $result = $this->ilDB->query($query);
427
428 $outfile_lines = '';
430 while ($row = $this->ilDB->fetchAssoc($result)) {
431 $outfile_lines .= "\r\n" . implode("\t", $row);
432 }
433 file_put_contents($this->getTestArchive() . self::DIR_SEP . self::TEST_LOG_FILENAME, $outfile_lines);
434
435 // Generate test pass overview
436 $test = new ilObjTest($this->test_obj_id, false);
437 if ($this->test_ref_id !== null) {
438 $test->setRefId($this->test_ref_id);
439 }
440
441 $gui = new ilParticipantsTestResultsGUI();
442 $gui->setTestObj($test);
443
444 $objectiveOrientedContainer = new ilTestObjectiveOrientedContainer();
445 $gui->setObjectiveParent($objectiveOrientedContainer);
446 $array_of_actives = array();
447 $participants = $test->getParticipants();
448
449 foreach ($participants as $key => $value) {
450 $array_of_actives[] = $key;
451 }
452 $output_template = $gui->createUserResults(true, false, true, $array_of_actives);
453
454 $filename = realpath($this->getTestArchive()) . self::DIR_SEP . 'participant_pass_overview.pdf';
456
457 return;
458 }
459
461 {
462 if (!$this->hasZipExportDirectory()) {
464 }
465 }
466
472 public function hasZipExportDirectory(): bool
473 {
474 return is_dir($this->getZipExportDirectory());
475 }
476
477 protected function createZipExportDirectory()
478 {
479 mkdir($this->getZipExportDirectory(), 0777, true);
480 }
481
487 public function getZipExportDirectory(): string
488 {
489 return $this->external_directory_path . self::DIR_SEP . $this->client_id . self::DIR_SEP . 'tst_data'
490 . self::DIR_SEP . self::EXPORT_DIRECTORY . self::DIR_SEP . 'tst_' . $this->test_obj_id;
491 }
492
498 public function compressTestArchive()
499 {
500 $this->updateTestArchive();
502
503 $zip_output_path = $this->getZipExportDirectory();
504 $zip_output_filename = 'test_archive_obj_' . $this->test_obj_id . '_' . time() . '_.zip';
505
506 ilFileUtils::zip($this->getTestArchive(), $zip_output_path . self::DIR_SEP . $zip_output_filename, true);
507 return;
508 }
509
510 #endregion
511
512 #region PassDataDirectory
513 // The pass data directory contains all data relevant for a participants pass.
514 // In addition to the test-archive-directory, this directory lives here:
515 // .../<year>/<month>/<day>/<ActiveFi>_<Pass>[_<Lastname>][_<Firstname>][_<Matriculation>]/
516 // Lastname, Firstname and Matriculation are not mandatory in the directory name.
517
526 protected function hasPassDataDirectory($active_fi, $pass): bool
527 {
528 return is_dir($this->getPassDataDirectory($active_fi, $pass));
529 }
530
539 protected function createPassDataDirectory($active_fi, $pass)
540 {
541 mkdir($this->getPassDataDirectory($active_fi, $pass), 0777, true);
542 return;
543 }
544
545 private function buildPassDataDirectory($active_fi, $pass): ?string
546 {
547 foreach ($this->archive_data_index as $data_index_entry) {
548 if ($data_index_entry != null && $data_index_entry['identifier'] == $active_fi . '|' . $pass) {
549 array_shift($data_index_entry);
550 return $this->getTestArchive() . self::DIR_SEP . implode(self::DIR_SEP, $data_index_entry);
551 }
552 }
553
554 return null;
555 }
556
565 protected function getPassDataDirectory($active_fi, $pass): ?string
566 {
567 $passDataDir = $this->buildPassDataDirectory($active_fi, $pass);
568
569 if (!$passDataDir) {
570 $test_obj = new ilObjTest($this->test_obj_id, false);
571 if ($test_obj->getAnonymity()) {
572 $firstname = 'anonym';
573 $lastname = '';
574 $matriculation = '0';
575 } else {
576 if ($this->getParticipantData()) {
577 $usrData = $this->getParticipantData()->getUserDataByActiveId($active_fi);
578 $firstname = $usrData['firstname'];
579 $lastname = $usrData['lastname'];
580 $matriculation = $usrData['matriculation'];
581 } else {
582 global $DIC;
583 $ilUser = $DIC['ilUser'];
584 $firstname = $ilUser->getFirstname();
585 $lastname = $ilUser->getLastname();
586 $matriculation = $ilUser->getMatriculation();
587 }
588 }
589
591 date(DATE_ISO8601),
592 $active_fi,
593 $pass,
594 $firstname,
595 $lastname,
596 $matriculation
597 );
598
599 $passDataDir = $this->buildPassDataDirectory($active_fi, $pass);
600 }
601
602 return $passDataDir;
603 }
604
615 protected function ensurePassDataDirectoryIsAvailable($active_fi, $pass)
616 {
617 if (!$this->hasPassDataDirectory($active_fi, $pass)) {
618 $this->createPassDataDirectory($active_fi, $pass);
619 }
620 return;
621 }
622
623 #endregion
624
625 #region PassMaterialsDirectory
626
635 protected function hasPassMaterialsDirectory($active_fi, $pass): bool
636 {
638 if (@is_dir($this->getPassMaterialsDirectory($active_fi, $pass))) {
639 return true;
640 }
641 return false;
642 }
643
652 protected function createPassMaterialsDirectory($active_fi, $pass): string
653 {
654 // Data are taken from the current user as the implementation expects the first interaction of the pass
655 // takes place from the usage/behaviour of the current user.
656
657 if ($this->getParticipantData()) {
658 $usrData = $this->getParticipantData()->getUserDataByActiveId($active_fi);
659 $user = new ilObjUser();
660 $user->setFirstname($usrData['firstname']);
661 $user->setLastname($usrData['lastname']);
662 $user->setMatriculation($usrData['matriculation']);
663 $user->setFirstname($usrData['firstname']);
664 } else {
665 global $DIC;
666 $ilUser = $DIC['ilUser'];
667 $user = $ilUser;
668 }
669
671 date(DATE_ISO8601),
672 $active_fi,
673 $pass,
674 $user->getFirstname(),
675 $user->getLastname(),
676 $user->getMatriculation()
677 );
678
679 $material_directory = $this->getPassMaterialsDirectory($active_fi, $pass);
680 mkdir($material_directory, 0777, true);
681 return $material_directory;
682 }
683
692 protected function getPassMaterialsDirectory($active_fi, $pass): string
693 {
694 $pass_data_directory = $this->getPassDataDirectory($active_fi, $pass);
695 return $pass_data_directory . self::DIR_SEP . self::PASS_MATERIALS_PATH_COMPONENT;
696 }
697
707 protected function ensurePassMaterialsDirectoryIsAvailable($active_fi, $pass)
708 {
709 if (!$this->hasPassMaterialsDirectory($active_fi, $pass)) {
710 $this->createPassMaterialsDirectory($active_fi, $pass);
711 }
712 }
713
714 #endregion
715
721 protected function readArchiveDataIndex(): array
722 {
727 $data_index_file = $this->getTestArchive() . self::DIR_SEP . self::DATA_INDEX_FILENAME;
728
729 $contents = array();
730
732 if (@file_exists($data_index_file)) {
733 $lines = explode("\n", file_get_contents($data_index_file));
734 foreach ($lines as $line) {
735 if (strlen($line) === 0) {
736 continue;
737 }
738 $line_items = explode('|', $line);
739 $line_data = [];
740 $line_data['identifier'] = $line_items[0] . '|' . $line_items[1];
741 $line_data['yyyy'] = $line_items[2];
742 $line_data['mm'] = $line_items[3];
743 $line_data['dd'] = $line_items[4];
744 $line_data['directory'] = $line_items[5];
745 $contents[] = $line_data;
746 }
747 }
748 return $contents;
749 }
750
763 protected function appendToArchiveDataIndex($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation)
764 {
765 $line = $this->determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation);
766
767 $this->archive_data_index[] = $line;
768 $output_contents = '';
769
770 foreach ($this->archive_data_index as $line_data) {
771 if ($line_data['identifier'] == "|") {
772 continue;
773 }
774 $output_contents .= implode('|', $line_data) . "\n";
775 }
776
777 file_put_contents($this->getTestArchive() . self::DIR_SEP . self::DATA_INDEX_FILENAME, $output_contents);
778 $this->readArchiveDataIndex();
779 return;
780 }
781
794 protected function determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation): array
795 {
796 $date = date_create_from_format(DATE_ISO8601, $date);
797 $line = array(
798 'identifier' => $active_fi . '|' . $pass,
799 'yyyy' => date_format($date, 'Y'),
800 'mm' => date_format($date, 'm'),
801 'dd' => date_format($date, 'd'),
802 'directory' => $active_fi . '_' . $pass . '_' . $user_firstname . '_' . $user_lastname . '_' . $matriculation
803 );
804 return $line;
805 }
806
814 protected function logArchivingProcess($message)
815 {
816 $archive = $this->getTestArchive() . self::DIR_SEP . self::ARCHIVE_LOG;
817 if (file_exists($archive)) {
818 $content = file_get_contents($archive) . "\n" . $message;
819 } else {
820 $content = $message;
821 }
822
823 file_put_contents($archive, $content);
824 }
825
834 protected function countFilesInDirectory($directory, $pattern = null): int
835 {
836 $filecount = 0;
837
839 if ($handle = opendir($directory)) {
840 while (($file = readdir($handle)) !== false) {
841 if (!in_array($file, array( '.', '..' )) && !is_dir($directory . $file)) {
842 if ($pattern && strpos($file, $pattern) === 0) {
843 $filecount++;
844 }
845 }
846 }
847 }
848 return $filecount;
849 }
850}
$filename
Definition: buildRTE.php:78
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
User class.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
handInTestResult($active_fi, $pass, $pdf_path)
Hands in an individual test result for a pass.
handInParticipantSubmission($active_fi, $pass, $pdf_path, $html_string)
Hands in a participants test submission ("a completed test") for archiving.
handInBestSolutionQuestionMaterial($question_fi, $orginial_filename, $file_path)
Hands in a file related to a question in context of the best solution.
compressTestArchive()
Generate the test archive for download.
hasPassMaterialsDirectory($active_fi, $pass)
Returns if the pass materials directory exists for a given pass.
countFilesInDirectory($directory, $pattern=null)
Returns the count of files in a directory, eventually matching the given, optional,...
ensureTestArchiveIsAvailable()
Ensures the availability of the test archive directory.
getTestArchive()
Returns the (theoretical) path to the archive directory of the test, this object is created for.
getZipExportDirectory()
Return the export directory, where zips are placed.
handInParticipantUploadedResults($active_fi, $pass, $tst_obj)
handInParticipantQuestionMaterial($active_fi, $pass, $question_fi, $original_filename, $file_path)
Hands in a particpants question material, such as an upload or other binary content.
getPassMaterialsDirectory($active_fi, $pass)
Returns the pass materials directory.
handInTestResultsOverview($html_string, $pdf_path)
Hands in a test results overview.
handInTestBestSolution($html_string, $pdf_path)
Hands in the best solution for a test.
hasPassDataDirectory($active_fi, $pass)
Checks if the directory for pass data is available.
setParticipantData($participantData)
readArchiveDataIndex()
Reads the archive data index.
getPassDataDirectory($active_fi, $pass)
Returns the pass data directory.
hasTestArchive()
Returns if the archive directory structure for the test the object is created for exists.
handInParticipantMisc($active_fi, $pass, $original_filename, $file_path)
Hands in a participants file, which is relevant for archiving but an unspecified type.
createPassDataDirectory($active_fi, $pass)
Creates pass data directory.
const TEST_BEST_SOLUTION_PATH_COMPONENT
buildPassDataDirectory($active_fi, $pass)
appendToArchiveDataIndex($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation)
Appends a line to the archive data index.
createPassMaterialsDirectory($active_fi, $pass)
Creates pass materials directory.
ensurePassMaterialsDirectoryIsAvailable($active_fi, $pass)
Ensures the availability of the pass materials directory.
const QUESTION_PATH_COMPONENT_PREFIX
updateTestArchive()
Replaces the test-log with the current one.
logArchivingProcess($message)
Logs to the archive log.
hasZipExportDirectory()
Returns if the export directory for zips exists.
createArchiveForTest()
Creates the directory for the test archive.
ensurePassDataDirectoryIsAvailable($active_fi, $pass)
Ensures the availability of the participant data directory.
determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation)
Determines the pass data path.
static generatePDF($pdf_output, $output_mode, $filename=null, $purpose=null)
const CLIENT_WEB_DIR
Definition: constants.php:47
global $DIC
Definition: feed.php:28
$ilUser
Definition: imgupload.php:34
const PDF_USER_RESULT
PDF Purposes.
Interface ilDBInterface.
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
string $key
Consumer key/client ID value.
Definition: System.php:193
$query
$message
Definition: xapiexit.php:32