ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
ilTestArchiver Class Reference
+ Collaboration diagram for ilTestArchiver:

Public Member Functions

 getParticipantData ()
 
 setParticipantData (ilTestParticipantData $participant_data)
 
 handInParticipantQuestionMaterial (int $active_fi, int $pass, int $question_fi, string $original_filename, string $file_path)
 
 handInParticipantMisc (int $active_fi, int $pass, string $original_filename, string $file_path)
 
 handInTestBestSolution (string $best_solution)
 
 handInParticipantUploadedResults (int $active_fi, int $pass, ilObjTest $tst_obj)
 
 handInBestSolutionQuestionMaterial (int $question_fi, string $orginial_filename, string $file_path)
 
 handInTestResult (int $active_fi, int $pass, string $pdf_path)
 
 updateTestArchive ()
 
 ensureZipExportDirectoryExists ()
 
 hasZipExportDirectory ()
 
 getZipExportDirectory ()
 
 compressTestArchive ()
 
 getResultsOfUserOutput (\ilObjTest $test_obj, ilTestSession $test_session, array $participant_data, int $active_id, int $attempt)
 

Data Fields

const DIR_SEP = DIRECTORY_SEPARATOR
 
const EXPORT_DIRECTORY = 'archive_exports'
 

Protected Member Functions

 hasTestArchive ()
 
 createArchiveForTest ()
 
 getTestArchive ()
 
 ensureTestArchiveIsAvailable ()
 
 createZipExportDirectory ()
 
 hasPassDataDirectory (int $active_fi, int $pass)
 
 createPassDataDirectory (int $active_fi, int $pass)
 
 getPassDataDirectory (int $active_fi, int $pass)
 
 ensurePassDataDirectoryIsAvailable (int $active_fi, int $pass)
 
 hasPassMaterialsDirectory (int $active_fi, int $pass)
 
 createPassMaterialsDirectory (int $active_fi, int $pass)
 
 getPassMaterialsDirectory (int $active_fi, int $pass)
 
 ensurePassMaterialsDirectoryIsAvailable (int $active_fi, int $pass)
 
 readArchiveDataIndex ()
 
 appendToArchiveDataIndex (string $date, int $active_fi, int $pass, string $user_firstname, string $user_lastname, string $matriculation)
 

Protected Attributes

ilTestHTMLGenerator $html_generator
 
ilTestParticipantData $participant_data = null
 
TestResultRepository $test_result_repository
 

Private Member Functions

 buildPassDataDirectory ($active_fi, $pass)
 
 determinePassDataPath (string $date, int $active_fi, int $pass, string $user_firstname, string $user_lastname, string $matriculation)
 
 createUserResultsForArchive (\ilObjTest $test_obj, array $active_ids,)
 
 getColumnsForAttemptOverviewTable ()
 
 getDataRetrievalForAttemptOverviewTable (array $result_data)
 
 logArchivingProcess (string $message)
 

Private Attributes

const PASS_MATERIALS_PATH_COMPONENT = 'materials'
 
const QUESTION_PATH_COMPONENT_PREFIX = 'q_'
 
const TEST_BEST_SOLUTION_PATH_COMPONENT = 'best_solution'
 
const HTML_BEST_SOLUTION_FILENAME = 'best_solution.html'
 
const TEST_MATERIALS_PATH_COMPONENT = 'materials'
 
const TEST_RESULT_FILENAME = 'test_result.html'
 
const LOG_DTSGROUP_FORMAT = 'D M j G:i:s T Y'
 
const LOG_ADDITION_STRING = ' Adding '
 
const TEST_LOG_FILENAME = 'test_log.xlsx'
 
const DATA_INDEX_FILENAME = 'data_index.csv'
 
const ARCHIVE_LOG = 'archive.log'
 
string $external_directory_path
 
string $client_id = CLIENT_ID
 
 $archive_data_index
 

Detailed Description

Author
Maximilian Becker mbeck.nosp@m.er@d.nosp@m.ataba.nosp@m.y.de

Definition at line 37 of file class.ilTestArchiver.php.

Member Function Documentation

◆ appendToArchiveDataIndex()

ilTestArchiver::appendToArchiveDataIndex ( string  $date,
int  $active_fi,
int  $pass,
string  $user_firstname,
string  $user_lastname,
string  $matriculation 
)
protected

Definition at line 480 of file class.ilTestArchiver.php.

References determinePassDataPath(), getTestArchive(), and readArchiveDataIndex().

Referenced by createPassMaterialsDirectory(), and getPassDataDirectory().

487  : void {
488  $line = $this->determinePassDataPath($date, $active_fi, $pass, $user_firstname, $user_lastname, $matriculation);
489 
490  $this->archive_data_index[] = $line;
491  $output_contents = '';
492 
493  foreach ($this->archive_data_index as $line_data) {
494  if ($line_data['identifier'] == "|") {
495  continue;
496  }
497  $output_contents .= implode('|', $line_data) . "\n";
498  }
499 
500  file_put_contents($this->getTestArchive() . DIRECTORY_SEPARATOR . self::DATA_INDEX_FILENAME, $output_contents);
501  $this->readArchiveDataIndex();
502  return;
503  }
determinePassDataPath(string $date, int $active_fi, int $pass, string $user_firstname, string $user_lastname, string $matriculation)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ buildPassDataDirectory()

ilTestArchiver::buildPassDataDirectory (   $active_fi,
  $pass 
)
private

Definition at line 343 of file class.ilTestArchiver.php.

References getTestArchive(), and null.

Referenced by getPassDataDirectory().

343  : ?string
344  {
345  foreach ($this->archive_data_index as $data_index_entry) {
346  if ($data_index_entry != null && $data_index_entry['identifier'] == $active_fi . '|' . $pass) {
347  array_shift($data_index_entry);
348  return $this->getTestArchive() . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $data_index_entry);
349  }
350  }
351 
352  return null;
353  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ compressTestArchive()

ilTestArchiver::compressTestArchive ( )

Definition at line 320 of file class.ilTestArchiver.php.

References ensureZipExportDirectoryExists(), getTestArchive(), getZipExportDirectory(), updateTestArchive(), and ilFileUtils\zip().

320  : void
321  {
322  $this->updateTestArchive();
324 
325  $zip_output_path = $this->getZipExportDirectory();
326  $zip_output_filename = 'test_archive_obj_' . $this->test_obj_id . '_' . time() . '.zip';
327 
328  ilFileUtils::zip($this->getTestArchive(), $zip_output_path . DIRECTORY_SEPARATOR . $zip_output_filename, true);
329  return;
330  }
static zip(string $a_dir, string $a_file, bool $compress_content=false)
+ Here is the call graph for this function:

◆ createArchiveForTest()

ilTestArchiver::createArchiveForTest ( )
protected

Definition at line 246 of file class.ilTestArchiver.php.

References getTestArchive(), and ilFileUtils\makeDirParents().

Referenced by ensureTestArchiveIsAvailable().

246  : void
247  {
249  }
static makeDirParents(string $a_dir)
Create a new directory and all parent directories.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createPassDataDirectory()

ilTestArchiver::createPassDataDirectory ( int  $active_fi,
int  $pass 
)
protected

Definition at line 337 of file class.ilTestArchiver.php.

References getPassDataDirectory().

Referenced by ensurePassDataDirectoryIsAvailable().

337  : void
338  {
339  mkdir($this->getPassDataDirectory($active_fi, $pass), 0777, true);
340  return;
341  }
getPassDataDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createPassMaterialsDirectory()

ilTestArchiver::createPassMaterialsDirectory ( int  $active_fi,
int  $pass 
)
protected

Data is taken from the current user as the implementation expects the first interaction of the pass takes place from the usage/behaviour of the current user. (skergomard, 11.09.24: Whatever the f*** this means.)

Definition at line 407 of file class.ilTestArchiver.php.

References appendToArchiveDataIndex(), getParticipantData(), getPassMaterialsDirectory(), and ILIAS\Repository\lng().

Referenced by ensurePassMaterialsDirectoryIsAvailable().

407  : string
408  {
414  $user = $this->user;
415 
416  if ($this->getParticipantData()) {
417  $usrData = $this->getParticipantData()->getUserDataByActiveId($active_fi);
418  $user = new ilObjUser();
419  $user->setFirstname($usrData['firstname'] ?? $this->lng->txt('deleted_user'));
420  $user->setLastname($usrData['lastname'] ?? '');
421  $user->setMatriculation($usrData['matriculation'] ?? '');
422  }
423 
425  date('c'),
426  $active_fi,
427  $pass,
428  $user->getFirstname(),
429  $user->getLastname(),
430  $user->getMatriculation()
431  );
432  $material_directory = $this->getPassMaterialsDirectory($active_fi, $pass);
433  mkdir($material_directory, 0777, true);
434  return $material_directory;
435  }
getPassMaterialsDirectory(int $active_fi, int $pass)
appendToArchiveDataIndex(string $date, int $active_fi, int $pass, string $user_firstname, string $user_lastname, string $matriculation)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createUserResultsForArchive()

ilTestArchiver::createUserResultsForArchive ( \ilObjTest  $test_obj,
array  $active_ids 
)
private

Definition at line 528 of file class.ilTestArchiver.php.

References $results, ilObjTest\_getResultPass(), ilTestParticipantData\getActiveIds(), ilObject\getRefId(), getResultsOfUserOutput(), ilObjTest\getTestId(), ilTestParticipantData\getUserDataByActiveId(), ILIAS\Repository\int(), ILIAS\Repository\lng(), ilTestParticipantData\load(), ilTestParticipantData\setActiveIdsFilter(), ilTestParticipantData\setParticipantAccessFilter(), and ILIAS\Repository\user().

Referenced by updateTestArchive().

531  : string {
532  $template = new ilTemplate('tpl.il_as_tst_participants_result_output.html', true, true, 'components/ILIAS/Test');
533 
534  $participant_data = new ilTestParticipantData($this->db, $this->lng);
536  $this->participant_access_filter_factory->getAccessResultsUserFilter($test_obj->getRefId())
537  );
539  $participant_data->load($test_obj->getTestId());
540 
541  $test_session_factory = new ilTestSessionFactory($test_obj, $this->db, $this->user);
542 
543  $count = 0;
544  foreach ($active_ids as $active_id) {
545  if (!in_array($active_id, $participant_data->getActiveIds())) {
546  continue;
547  }
548 
549  $count++;
550  $results = '';
551  if ($active_id > 0) {
553  $test_obj,
554  $test_session_factory->getSession($active_id),
556  (int) $active_id,
557  ilObjTest::_getResultPass($active_id)
558  );
559  }
560  if ($count < count($active_ids)) {
561  $template->touchBlock('break');
562  }
563  $template->setCurrentBlock('user_result');
564  $template->setVariable('USER_RESULT', $results);
565  $template->parseCurrentBlock();
566  }
567 
568  return $template->get();
569  }
ilTestParticipantData $participant_data
setParticipantAccessFilter(Closure $participantAccessFilter)
setActiveIdsFilter(array $active_ids_filter)
static _getResultPass($active_id)
Retrieves the pass number that should be counted for a given user.
$results
getResultsOfUserOutput(\ilObjTest $test_obj, ilTestSession $test_session, array $participant_data, int $active_id, int $attempt)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ createZipExportDirectory()

ilTestArchiver::createZipExportDirectory ( )
protected

Definition at line 309 of file class.ilTestArchiver.php.

References getZipExportDirectory().

Referenced by ensureZipExportDirectoryExists().

309  : void
310  {
311  mkdir($this->getZipExportDirectory(), 0777, true);
312  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ determinePassDataPath()

ilTestArchiver::determinePassDataPath ( string  $date,
int  $active_fi,
int  $pass,
string  $user_firstname,
string  $user_lastname,
string  $matriculation 
)
private

Definition at line 505 of file class.ilTestArchiver.php.

Referenced by appendToArchiveDataIndex().

512  : array {
513  $parsed_date = date_create_from_format('Y-m-d\TH:i:sP', $date);
514  if (!$parsed_date) {
515  throw new Exception('Invalid date format. Expected ISO 8601 format.');
516  }
517 
518  $line = [
519  'identifier' => $active_fi . '|' . $pass,
520  'yyyy' => date_format($parsed_date, 'Y'),
521  'mm' => date_format($parsed_date, 'm'),
522  'dd' => date_format($parsed_date, 'd'),
523  'directory' => $active_fi . '_' . $pass . '_' . $user_firstname . '_' . $user_lastname . '_' . $matriculation
524  ];
525  return $line;
526  }
+ Here is the caller graph for this function:

◆ ensurePassDataDirectoryIsAvailable()

ilTestArchiver::ensurePassDataDirectoryIsAvailable ( int  $active_fi,
int  $pass 
)
protected

Definition at line 391 of file class.ilTestArchiver.php.

References createPassDataDirectory(), and hasPassDataDirectory().

Referenced by handInParticipantMisc(), handInParticipantQuestionMaterial(), handInParticipantUploadedResults(), and handInTestResult().

391  : void
392  {
393  if (!$this->hasPassDataDirectory($active_fi, $pass)) {
394  $this->createPassDataDirectory($active_fi, $pass);
395  }
396  return;
397  }
createPassDataDirectory(int $active_fi, int $pass)
hasPassDataDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ensurePassMaterialsDirectoryIsAvailable()

ilTestArchiver::ensurePassMaterialsDirectoryIsAvailable ( int  $active_fi,
int  $pass 
)
protected

Definition at line 443 of file class.ilTestArchiver.php.

References createPassMaterialsDirectory(), and hasPassMaterialsDirectory().

Referenced by handInParticipantUploadedResults().

443  : void
444  {
445  if (!$this->hasPassMaterialsDirectory($active_fi, $pass)) {
446  $this->createPassMaterialsDirectory($active_fi, $pass);
447  }
448  }
createPassMaterialsDirectory(int $active_fi, int $pass)
hasPassMaterialsDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ensureTestArchiveIsAvailable()

ilTestArchiver::ensureTestArchiveIsAvailable ( )
protected

Definition at line 258 of file class.ilTestArchiver.php.

References createArchiveForTest(), and hasTestArchive().

Referenced by handInBestSolutionQuestionMaterial(), handInParticipantMisc(), handInParticipantQuestionMaterial(), handInParticipantUploadedResults(), handInTestBestSolution(), and handInTestResult().

258  : void
259  {
260  if (!$this->hasTestArchive()) {
261  $this->createArchiveForTest();
262  }
263  return;
264  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ensureZipExportDirectoryExists()

ilTestArchiver::ensureZipExportDirectoryExists ( )

Definition at line 297 of file class.ilTestArchiver.php.

References createZipExportDirectory(), and hasZipExportDirectory().

Referenced by compressTestArchive().

297  : void
298  {
299  if (!$this->hasZipExportDirectory()) {
300  $this->createZipExportDirectory();
301  }
302  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getColumnsForAttemptOverviewTable()

ilTestArchiver::getColumnsForAttemptOverviewTable ( )
private

Definition at line 644 of file class.ilTestArchiver.php.

References ILIAS\Repository\lng().

Referenced by getResultsOfUserOutput().

644  : array
645  {
646  $cf = $this->ui_factory->table()->column();
647  $columns = [
648  'order' => $cf->number($this->lng->txt('order')),
649  'question_id' => $cf->number($this->lng->txt('question_id')),
650  'title' => $cf->text($this->lng->txt('tst_question_title')),
651  'reachable_points' => $cf->number($this->lng->txt('tst_maximum_points')),
652  'reached_points' => $cf->number($this->lng->txt('tst_reached_points'))
653  ];
654  $columns['solved'] = $cf->text($this->lng->txt('tst_percent_solved'));
655  return $columns;
656  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getDataRetrievalForAttemptOverviewTable()

ilTestArchiver::getDataRetrievalForAttemptOverviewTable ( array  $result_data)
private

Definition at line 658 of file class.ilTestArchiver.php.

References ILIAS\UI\Implementation\Component\Table\$range, ILIAS\GlobalScreen\Provider\__construct(), and ILIAS\UI\Component\Table\DataRowBuilder\buildDataRow().

Referenced by getResultsOfUserOutput().

658  : DataRetrieval
659  {
660  return new class ($result_data) implements DataRetrieval {
661  public function __construct(
662  private readonly array $result_data
663  ) {
664  }
665 
666  public function getRows(
667  DataRowBuilder $row_builder,
668  array $visible_column_ids,
669  Range $range,
670  Order $order,
671  ?array $filter_data,
672  ?array $additional_parameters
673  ): \Generator {
674  $i = 1;
675  foreach ($this->result_data as $result) {
676  if (!isset($result['qid'])) {
677  continue;
678  }
679  yield $row_builder->buildDataRow(
680  (string) $result['qid'],
681  [
682  'order' => $i++,
683  'question_id' => $result['qid'],
684  'title' => $result['title'],
685  'reachable_points' => $result['max'],
686  'reached_points' => $result['reached'],
687  'solved' => $result['percent']
688  ]
689  );
690  }
691  }
692 
693  public function getTotalRowCount(
694  ?array $filter_data,
695  ?array $additional_parameters
696  ): ?int {
697  return count($this->result_data);
698  }
699  };
700  }
Both the subject and the direction need to be specified when expressing an order. ...
Definition: Order.php:28
buildDataRow(string $id, array $record)
__construct(Container $dic, ilPlugin $plugin)
A simple class to express a naive range of whole positive numbers.
Definition: Range.php:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getParticipantData()

ilTestArchiver::getParticipantData ( )

Definition at line 94 of file class.ilTestArchiver.php.

References $participant_data.

Referenced by createPassMaterialsDirectory(), and getPassDataDirectory().

+ Here is the caller graph for this function:

◆ getPassDataDirectory()

ilTestArchiver::getPassDataDirectory ( int  $active_fi,
int  $pass 
)
protected

Definition at line 355 of file class.ilTestArchiver.php.

References appendToArchiveDataIndex(), buildPassDataDirectory(), getParticipantData(), ILIAS\Repository\lng(), null, and ILIAS\Repository\user().

Referenced by createPassDataDirectory(), getPassMaterialsDirectory(), handInParticipantMisc(), handInParticipantQuestionMaterial(), handInTestResult(), and hasPassDataDirectory().

355  : ?string
356  {
357  $pass_data_dir = $this->buildPassDataDirectory($active_fi, $pass);
358 
359  if ($pass_data_dir !== null) {
360  return $pass_data_dir;
361  }
362 
363  $test_obj = new ilObjTest($this->test_obj_id, false);
364  if ($test_obj->getAnonymity()) {
365  $firstname = $this->lng->txt('anonymous');
366  $lastname = '';
367  $matriculation = '';
368  } elseif ($this->getParticipantData()) {
369  $usr_data = $this->getParticipantData()->getUserDataByActiveId($active_fi);
370  $firstname = $usr_data['firstname'] ?? $this->lng->txt('deleted_user');
371  $lastname = $usr_data['lastname'] ?? '';
372  $matriculation = $usr_data['matriculation'] ?? '';
373  } else {
374  $firstname = $this->user->getFirstname();
375  $lastname = $this->user->getLastname();
376  $matriculation = $this->user->getMatriculation();
377  }
378 
380  date(DATE_ISO8601),
381  $active_fi,
382  $pass,
383  $firstname,
384  $lastname,
385  $matriculation
386  );
387 
388  return $this->buildPassDataDirectory($active_fi, $pass);
389  }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
buildPassDataDirectory($active_fi, $pass)
appendToArchiveDataIndex(string $date, int $active_fi, int $pass, string $user_firstname, string $user_lastname, string $matriculation)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getPassMaterialsDirectory()

ilTestArchiver::getPassMaterialsDirectory ( int  $active_fi,
int  $pass 
)
protected

Definition at line 437 of file class.ilTestArchiver.php.

References getPassDataDirectory().

Referenced by createPassMaterialsDirectory(), handInParticipantUploadedResults(), and hasPassMaterialsDirectory().

437  : string
438  {
439  $pass_data_directory = $this->getPassDataDirectory($active_fi, $pass);
440  return $pass_data_directory . DIRECTORY_SEPARATOR . self::PASS_MATERIALS_PATH_COMPONENT;
441  }
getPassDataDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getResultsOfUserOutput()

ilTestArchiver::getResultsOfUserOutput ( \ilObjTest  $test_obj,
ilTestSession  $test_session,
array  $participant_data,
int  $active_id,
int  $attempt 
)

Definition at line 571 of file class.ilTestArchiver.php.

References $results, ilTestSession\getActiveId(), ilObjTest\getAnonymity(), getColumnsForAttemptOverviewTable(), getDataRetrievalForAttemptOverviewTable(), ilObjTest\getTestResult(), ilObjTest\isShowExamIdInTestResultsEnabled(), ILIAS\Repository\lng(), ilObjTest\lookupExamId(), and ILIAS\Repository\user().

Referenced by createUserResultsForArchive().

577  : string {
578  $template = new ilTemplate('tpl.il_as_tst_results_participant.html', true, true, 'components/ILIAS/Test');
579 
580  $uname = "{$participant_data['firstname']} {$participant_data['lastname']}";
581  if ($test_obj->getAnonymity()) {
582  $uname = $this->lng->txt('anonymous');
583  }
584 
585  $test_result_title_builder = new ResultsTitleBuilder($this->lng, $this->obj_cache);
586 
587  $result_array = $test_obj->getTestResult(
588  $active_id,
589  $attempt,
590  false,
591  true
592  );
593 
594  $table = $this->ui_factory->table()->data(
595  $this->getDataRetrievalForAttemptOverviewTable($result_array),
596  $test_result_title_builder->getPassDetailsHeaderLabel($attempt + 1),
598  )->withRequest($this->request);
599  $template->setVariable(
600  'PASS_DETAILS',
601  $this->ui_renderer->render($table)
602  );
603 
604  if ($test_obj->isShowExamIdInTestResultsEnabled()) {
605  $template->setCurrentBlock('exam_id_footer');
606  $template->setVariable('EXAM_ID_VAL', ilObjTest::lookupExamId(
607  $test_session->getActiveId(),
608  $attempt
609  ));
610  $template->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
611  $template->parseCurrentBlock();
612  }
613 
614  $template->setCurrentBlock('participant_block_id');
615  $template->setVariable('PARTICIPANT_BLOCK_ID', "participant_active_{$active_id}");
616  $template->parseCurrentBlock();
617 
618  $template->setVariable('TEXT_HEADING', sprintf($this->lng->txt('tst_result_user_name'), $uname));
619 
620  if ($participant_data['matriculation'] !== '') {
621  $template->setVariable('USER_DATA', "{$this->lng->txt('matriculation')}: {$participant_data['matriculation']}");
622  }
623 
624  $results = $this->test_result_repository->getTestResult($active_id);
625 
626  $status = $this->lng->txt($results->isPassed() ? 'passed_official' : 'failed_official');
627  $template->setVariable(
628  'GRADING_MESSAGE',
629  "{$this->lng->txt('passed_status')}: {$status}<br>"
630  . "{$this->lng->txt('tst_mark')}: {$results->getMarkOfficial()}"
631  );
632 
633  $template->setVariable('PASS_FINISH_DATE_LABEL', $this->lng->txt('tst_pass_finished_on'));
634  $template->setVariable(
635  'PASS_FINISH_DATE_VALUE',
636  (new \DateTimeImmutable('@' . ilObjTest::lookupLastTestPassAccess($active_id, $attempt)))
637  ->setTimezone(new DateTimeZone($this->user->getTimeZone()))
638  ->format($this->user->getDateTimeFormat()->toString())
639  );
640 
641  return $template->get();
642  }
ilTestParticipantData $participant_data
$results
getDataRetrievalForAttemptOverviewTable(array $result_data)
static lookupExamId($active_id, $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getTestArchive()

ilTestArchiver::getTestArchive ( )
protected

Definition at line 251 of file class.ilTestArchiver.php.

Referenced by appendToArchiveDataIndex(), buildPassDataDirectory(), compressTestArchive(), createArchiveForTest(), handInBestSolutionQuestionMaterial(), handInTestBestSolution(), hasTestArchive(), logArchivingProcess(), readArchiveDataIndex(), and updateTestArchive().

251  : string
252  {
253  $test_archive_directory = $this->external_directory_path . DIRECTORY_SEPARATOR . $this->client_id . DIRECTORY_SEPARATOR . 'tst_data'
254  . DIRECTORY_SEPARATOR . 'archive' . DIRECTORY_SEPARATOR . 'tst_' . $this->test_obj_id;
255  return $test_archive_directory;
256  }
+ Here is the caller graph for this function:

◆ getZipExportDirectory()

ilTestArchiver::getZipExportDirectory ( )

Definition at line 314 of file class.ilTestArchiver.php.

Referenced by compressTestArchive(), createZipExportDirectory(), and hasZipExportDirectory().

314  : string
315  {
316  return $this->external_directory_path . DIRECTORY_SEPARATOR . $this->client_id . DIRECTORY_SEPARATOR . 'tst_data'
317  . DIRECTORY_SEPARATOR . self::EXPORT_DIRECTORY . DIRECTORY_SEPARATOR . 'tst_' . $this->test_obj_id;
318  }
+ Here is the caller graph for this function:

◆ handInBestSolutionQuestionMaterial()

ilTestArchiver::handInBestSolutionQuestionMaterial ( int  $question_fi,
string  $orginial_filename,
string  $file_path 
)

Definition at line 202 of file class.ilTestArchiver.php.

References ensureTestArchiveIsAvailable(), getTestArchive(), and logArchivingProcess().

206  : void {
208 
209  $best_solution_path = $this->getTestArchive() . DIRECTORY_SEPARATOR . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
210  if (!is_dir($best_solution_path)) {
211  mkdir($best_solution_path, 0777, true);
212  }
213 
214  $materials_path = $best_solution_path . DIRECTORY_SEPARATOR . self::TEST_MATERIALS_PATH_COMPONENT;
215  if (!is_dir($materials_path)) {
216  mkdir($materials_path, 0777, true);
217  }
218 
219  $question_materials_path = $materials_path . DIRECTORY_SEPARATOR . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
220  if (!is_dir($question_materials_path)) {
221  mkdir($question_materials_path, 0777, true);
222  }
223 
224  copy($file_path, $question_materials_path . DIRECTORY_SEPARATOR . $orginial_filename);
225 
226  $this->logArchivingProcess(
227  date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
228  . $question_materials_path . DIRECTORY_SEPARATOR . $orginial_filename
229  );
230  }
logArchivingProcess(string $message)
+ Here is the call graph for this function:

◆ handInParticipantMisc()

ilTestArchiver::handInParticipantMisc ( int  $active_fi,
int  $pass,
string  $original_filename,
string  $file_path 
)

Definition at line 128 of file class.ilTestArchiver.php.

References ensurePassDataDirectoryIsAvailable(), ensureTestArchiveIsAvailable(), getPassDataDirectory(), and logArchivingProcess().

133  : void {
135  $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
136  $new_path = $this->getPassDataDirectory($active_fi, $pass) . DIRECTORY_SEPARATOR . $original_filename;
137  copy($file_path, $new_path);
138  $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
139  }
getPassDataDirectory(int $active_fi, int $pass)
ensurePassDataDirectoryIsAvailable(int $active_fi, int $pass)
logArchivingProcess(string $message)
+ Here is the call graph for this function:

◆ handInParticipantQuestionMaterial()

ilTestArchiver::handInParticipantQuestionMaterial ( int  $active_fi,
int  $pass,
int  $question_fi,
string  $original_filename,
string  $file_path 
)

Definition at line 104 of file class.ilTestArchiver.php.

References ensurePassDataDirectoryIsAvailable(), ensureTestArchiveIsAvailable(), getPassDataDirectory(), and logArchivingProcess().

110  : void {
112  $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
113 
114  $pass_question_directory = $this->getPassDataDirectory($active_fi, $pass)
115  . DIRECTORY_SEPARATOR . self::QUESTION_PATH_COMPONENT_PREFIX . $question_fi;
116  if (!is_dir($pass_question_directory)) {
117  mkdir($pass_question_directory, 0777, true);
118  }
119 
120  copy($file_path, $pass_question_directory . DIRECTORY_SEPARATOR . $original_filename);
121 
122  $this->logArchivingProcess(
123  date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
124  . $pass_question_directory . DIRECTORY_SEPARATOR . $original_filename
125  );
126  }
getPassDataDirectory(int $active_fi, int $pass)
ensurePassDataDirectoryIsAvailable(int $active_fi, int $pass)
logArchivingProcess(string $message)
+ Here is the call graph for this function:

◆ handInParticipantUploadedResults()

ilTestArchiver::handInParticipantUploadedResults ( int  $active_fi,
int  $pass,
ilObjTest  $tst_obj 
)

Definition at line 165 of file class.ilTestArchiver.php.

References ensurePassDataDirectoryIsAvailable(), ensurePassMaterialsDirectoryIsAvailable(), ensureTestArchiveIsAvailable(), getPassMaterialsDirectory(), ilObjTest\getQuestionDataset(), ilObjTest\getQuestionsOfPass(), ilObjTest\getTextAnswer(), and null.

169  : void {
170  $questions = $tst_obj->getQuestionsOfPass($active_fi, $pass);
171  foreach ($questions as $question) {
172  $question = $tst_obj->getQuestionDataset($question['question_fi']);
173  if ($question->type_tag === 'assFileUpload') {
175  $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
176  $this->ensurePassMaterialsDirectoryIsAvailable($active_fi, $pass);
177  $pass_material_directory = $this->getPassMaterialsDirectory($active_fi, $pass);
178  $archive_folder = $pass_material_directory . DIRECTORY_SEPARATOR . $question->question_id . DIRECTORY_SEPARATOR;
179  if (!file_exists($archive_folder)) {
180  mkdir($archive_folder, 0777, true);
181  }
182  $resource_id = $tst_obj->getTextAnswer($active_fi, $question->question_id, $pass);
183  if ($resource_id === '') {
184  continue;
185  }
186  $irss_unique_id = $this->irss->manage()->find($resource_id);
187  if ($irss_unique_id != null) {
188  $resource = $this->irss->manage()->getResource($irss_unique_id);
189  $information = $resource->getCurrentRevision()->getInformation();
190  $stream = $this->irss->consume()->stream($irss_unique_id);
191  // this feels unnecessary..
192  $file_stream = fopen($stream->getStream()->getMetadata('uri'), 'r');
193  $file_content = stream_get_contents($file_stream);
194  fclose($file_stream);
195  $target_destination = $archive_folder . $information->getTitle();
196  file_put_contents($target_destination, $file_content);
197  }
198  }
199  }
200  }
ensurePassDataDirectoryIsAvailable(int $active_fi, int $pass)
getQuestionsOfPass(int $active_id, int $pass)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
getPassMaterialsDirectory(int $active_fi, int $pass)
getQuestionDataset($question_id)
Returns the dataset for a given question id.
getTextAnswer($active_id, $question_id, $pass=null)
Returns the text answer of a given user for a given question.
ensurePassMaterialsDirectoryIsAvailable(int $active_fi, int $pass)
+ Here is the call graph for this function:

◆ handInTestBestSolution()

ilTestArchiver::handInTestBestSolution ( string  $best_solution)

Definition at line 141 of file class.ilTestArchiver.php.

References ensureTestArchiveIsAvailable(), getTestArchive(), and logArchivingProcess().

141  : void
142  {
144 
145  $best_solution_path = $this->getTestArchive() . DIRECTORY_SEPARATOR . self::TEST_BEST_SOLUTION_PATH_COMPONENT;
146  if (!is_dir($best_solution_path)) {
147  mkdir($best_solution_path, 0777, true);
148  }
149 
150  $this->html_generator->generateHTML(
151  $best_solution,
152  $best_solution_path . DIRECTORY_SEPARATOR . self::HTML_BEST_SOLUTION_FILENAME
153  );
154 
155  $this->logArchivingProcess(
156  date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING
157  . $best_solution_path . DIRECTORY_SEPARATOR . self::HTML_BEST_SOLUTION_FILENAME
158  );
159 
160  $this->logArchivingProcess(
161  date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $best_solution_path
162  );
163  }
logArchivingProcess(string $message)
+ Here is the call graph for this function:

◆ handInTestResult()

ilTestArchiver::handInTestResult ( int  $active_fi,
int  $pass,
string  $pdf_path 
)

Definition at line 232 of file class.ilTestArchiver.php.

References ensurePassDataDirectoryIsAvailable(), ensureTestArchiveIsAvailable(), getPassDataDirectory(), and logArchivingProcess().

232  : void
233  {
235  $this->ensurePassDataDirectoryIsAvailable($active_fi, $pass);
236  $new_path = $this->getPassDataDirectory($active_fi, $pass) . DIRECTORY_SEPARATOR . self::TEST_RESULT_FILENAME;
237  copy($pdf_path, $new_path);
238  $this->logArchivingProcess(date(self::LOG_DTSGROUP_FORMAT) . self::LOG_ADDITION_STRING . $new_path);
239  }
getPassDataDirectory(int $active_fi, int $pass)
ensurePassDataDirectoryIsAvailable(int $active_fi, int $pass)
logArchivingProcess(string $message)
+ Here is the call graph for this function:

◆ hasPassDataDirectory()

ilTestArchiver::hasPassDataDirectory ( int  $active_fi,
int  $pass 
)
protected

Definition at line 332 of file class.ilTestArchiver.php.

References getPassDataDirectory().

Referenced by ensurePassDataDirectoryIsAvailable().

332  : bool
333  {
334  return is_dir($this->getPassDataDirectory($active_fi, $pass));
335  }
getPassDataDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasPassMaterialsDirectory()

ilTestArchiver::hasPassMaterialsDirectory ( int  $active_fi,
int  $pass 
)
protected

Definition at line 399 of file class.ilTestArchiver.php.

References getPassMaterialsDirectory().

Referenced by ensurePassMaterialsDirectoryIsAvailable().

399  : bool
400  {
401  if (is_dir($this->getPassMaterialsDirectory($active_fi, $pass))) {
402  return true;
403  }
404  return false;
405  }
getPassMaterialsDirectory(int $active_fi, int $pass)
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasTestArchive()

ilTestArchiver::hasTestArchive ( )
protected

Definition at line 241 of file class.ilTestArchiver.php.

References getTestArchive().

Referenced by ensureTestArchiveIsAvailable().

241  : bool
242  {
243  return is_dir($this->getTestArchive());
244  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ hasZipExportDirectory()

ilTestArchiver::hasZipExportDirectory ( )

Definition at line 304 of file class.ilTestArchiver.php.

References getZipExportDirectory().

Referenced by ensureZipExportDirectoryExists().

304  : bool
305  {
306  return is_dir($this->getZipExportDirectory());
307  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ logArchivingProcess()

ilTestArchiver::logArchivingProcess ( string  $message)
private

Definition at line 702 of file class.ilTestArchiver.php.

References $message, and getTestArchive().

Referenced by handInBestSolutionQuestionMaterial(), handInParticipantMisc(), handInParticipantQuestionMaterial(), handInTestBestSolution(), and handInTestResult().

702  : void
703  {
704  $archive = $this->getTestArchive() . DIRECTORY_SEPARATOR . self::ARCHIVE_LOG;
705  if (file_exists($archive)) {
706  $content = file_get_contents($archive) . "\n" . $message;
707  } else {
708  $content = $message;
709  }
710 
711  file_put_contents($archive, $content);
712  }
$message
Definition: xapiexit.php:31
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ readArchiveDataIndex()

ilTestArchiver::readArchiveDataIndex ( )
protected

The Archive Data Index is a csv-file containing the following columns <active_fi>|<pass>|<yyyy>|<mm>||<directory>

PhpUsageOfSilenceOperatorInspection

Definition at line 450 of file class.ilTestArchiver.php.

References getTestArchive().

Referenced by appendToArchiveDataIndex().

450  : array
451  {
456  $data_index_file = $this->getTestArchive() . DIRECTORY_SEPARATOR . self::DATA_INDEX_FILENAME;
457 
458  $contents = [];
459 
461  if (@file_exists($data_index_file)) {
462  $lines = explode("\n", file_get_contents($data_index_file));
463  foreach ($lines as $line) {
464  if (strlen($line) === 0) {
465  continue;
466  }
467  $line_items = explode('|', $line);
468  $line_data = [];
469  $line_data['identifier'] = $line_items[0] . '|' . $line_items[1];
470  $line_data['yyyy'] = $line_items[2];
471  $line_data['mm'] = $line_items[3];
472  $line_data['dd'] = $line_items[4];
473  $line_data['directory'] = $line_items[5];
474  $contents[] = $line_data;
475  }
476  }
477  return $contents;
478  }
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ setParticipantData()

ilTestArchiver::setParticipantData ( ilTestParticipantData  $participant_data)

Definition at line 99 of file class.ilTestArchiver.php.

References $participant_data.

Referenced by ilTestArchiveService\archiveActivesPass().

99  : void
100  {
101  $this->participant_data = $participant_data;
102  }
ilTestParticipantData $participant_data
+ Here is the caller graph for this function:

◆ updateTestArchive()

ilTestArchiver::updateTestArchive ( )

Definition at line 266 of file class.ilTestArchiver.php.

References $filename, createUserResultsForArchive(), getTestArchive(), and null.

Referenced by compressTestArchive().

266  : void
267  {
268  $this->log_viewer->getLogExportForRefjId(
269  $this->test_ref_id
270  )->writeToFile(
271  $this->getTestArchive() . DIRECTORY_SEPARATOR . self::TEST_LOG_FILENAME
272  );
273 
274  // Generate test pass overview
275  $test = new ilObjTest($this->test_obj_id, false);
276  if ($this->test_ref_id !== null) {
277  $test->setRefId($this->test_ref_id);
278  }
279 
280  $array_of_actives = [];
281  $participants = $test->getParticipants();
282 
283  foreach (array_keys($participants) as $key) {
284  $array_of_actives[] = $key;
285  }
286 
287  $filename = realpath($this->getTestArchive()) . DIRECTORY_SEPARATOR . 'participant_attempt_overview.html';
288  $this->html_generator->generateHTML(
290  $test,
291  $array_of_actives
292  ),
293  $filename
294  );
295  }
createUserResultsForArchive(\ilObjTest $test_obj, array $active_ids,)
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
$filename
Definition: buildRTE.php:78
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $archive_data_index

ilTestArchiver::$archive_data_index
private

Definition at line 61 of file class.ilTestArchiver.php.

◆ $client_id

string ilTestArchiver::$client_id = CLIENT_ID
private

Definition at line 60 of file class.ilTestArchiver.php.

◆ $external_directory_path

string ilTestArchiver::$external_directory_path
private

Definition at line 59 of file class.ilTestArchiver.php.

◆ $html_generator

ilTestHTMLGenerator ilTestArchiver::$html_generator
protected

Definition at line 63 of file class.ilTestArchiver.php.

◆ $participant_data

ilTestParticipantData ilTestArchiver::$participant_data = null
protected

Definition at line 65 of file class.ilTestArchiver.php.

Referenced by getParticipantData(), and setParticipantData().

◆ $test_result_repository

TestResultRepository ilTestArchiver::$test_result_repository
protected

Definition at line 67 of file class.ilTestArchiver.php.

◆ ARCHIVE_LOG

const ilTestArchiver::ARCHIVE_LOG = 'archive.log'
private

Definition at line 57 of file class.ilTestArchiver.php.

◆ DATA_INDEX_FILENAME

const ilTestArchiver::DATA_INDEX_FILENAME = 'data_index.csv'
private

Definition at line 56 of file class.ilTestArchiver.php.

◆ DIR_SEP

const ilTestArchiver::DIR_SEP = DIRECTORY_SEPARATOR

Definition at line 39 of file class.ilTestArchiver.php.

◆ EXPORT_DIRECTORY

const ilTestArchiver::EXPORT_DIRECTORY = 'archive_exports'

Definition at line 41 of file class.ilTestArchiver.php.

Referenced by ilTestExportOptionARC\getDirectory().

◆ HTML_BEST_SOLUTION_FILENAME

const ilTestArchiver::HTML_BEST_SOLUTION_FILENAME = 'best_solution.html'
private

Definition at line 47 of file class.ilTestArchiver.php.

◆ LOG_ADDITION_STRING

const ilTestArchiver::LOG_ADDITION_STRING = ' Adding '
private

Definition at line 53 of file class.ilTestArchiver.php.

◆ LOG_DTSGROUP_FORMAT

const ilTestArchiver::LOG_DTSGROUP_FORMAT = 'D M j G:i:s T Y'
private

Definition at line 52 of file class.ilTestArchiver.php.

◆ PASS_MATERIALS_PATH_COMPONENT

const ilTestArchiver::PASS_MATERIALS_PATH_COMPONENT = 'materials'
private

Definition at line 43 of file class.ilTestArchiver.php.

◆ QUESTION_PATH_COMPONENT_PREFIX

const ilTestArchiver::QUESTION_PATH_COMPONENT_PREFIX = 'q_'
private

Definition at line 44 of file class.ilTestArchiver.php.

◆ TEST_BEST_SOLUTION_PATH_COMPONENT

const ilTestArchiver::TEST_BEST_SOLUTION_PATH_COMPONENT = 'best_solution'
private

Definition at line 46 of file class.ilTestArchiver.php.

◆ TEST_LOG_FILENAME

const ilTestArchiver::TEST_LOG_FILENAME = 'test_log.xlsx'
private

Definition at line 55 of file class.ilTestArchiver.php.

◆ TEST_MATERIALS_PATH_COMPONENT

const ilTestArchiver::TEST_MATERIALS_PATH_COMPONENT = 'materials'
private

Definition at line 48 of file class.ilTestArchiver.php.

◆ TEST_RESULT_FILENAME

const ilTestArchiver::TEST_RESULT_FILENAME = 'test_result.html'
private

Definition at line 50 of file class.ilTestArchiver.php.


The documentation for this class was generated from the following file: