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.