ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.assFileUpload.php
Go to the documentation of this file.
1 <?php
2  /*
3  +----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +----------------------------------------------------------------------------+
22 */
23 include_once "./Modules/TestQuestionPool/classes/class.assQuestion.php";
24 include_once "./Modules/Test/classes/inc.AssessmentConstants.php";
25 
35 {
36  protected $maxsize;
37  protected $allowedextensions;
38 
47  protected $completion_by_submission = false;
48 
61  function __construct(
62  $title = "",
63  $comment = "",
64  $author = "",
65  $owner = -1,
66  $question = ""
67  )
68  {
70  }
71 
77  public function isComplete()
78  {
79  if (strlen($this->title) and ($this->author) and ($this->question) and ($this->getMaximumPoints() >= 0) and is_numeric($this->getMaximumPoints()))
80  {
81  return true;
82  }
83  else
84  {
85  return false;
86  }
87  }
88 
93  public function saveToDb($original_id = "")
94  {
95  global $ilDB;
96 
98 
99  // save additional data
100 
101  $affectedRows = $ilDB->manipulateF("DELETE FROM " . $this->getAdditionalTableName() . " WHERE question_fi = %s",
102  array("integer"),
103  array($this->getId())
104  );
105  $affectedRows = $ilDB->manipulateF("INSERT INTO " . $this->getAdditionalTableName() . " (question_fi, maxsize, allowedextensions, compl_by_submission) VALUES (%s, %s, %s, %s)",
106  array("integer", "float", "text", "integer"),
107  array(
108  $this->getId(),
109  (strlen($this->getMaxSize())) ? $this->getMaxSize() : NULL,
110  (strlen($this->getAllowedExtensions())) ? $this->getAllowedExtensions() : NULL,
111  (int)$this->isCompletionBySubmissionEnabled()
112  )
113  );
115  }
116 
123  public function loadFromDb($question_id)
124  {
125  global $ilDB;
126  $result = $ilDB->queryF("SELECT qpl_questions.*, " . $this->getAdditionalTableName() . ".* FROM qpl_questions LEFT JOIN " . $this->getAdditionalTableName() . " ON " . $this->getAdditionalTableName() . ".question_fi = qpl_questions.question_id WHERE qpl_questions.question_id = %s",
127  array("integer"),
128  array($question_id)
129  );
130  if ($result->numRows() == 1)
131  {
132  $data = $ilDB->fetchAssoc($result);
133  $this->setId($question_id);
134  $this->setTitle($data["title"]);
135  $this->setComment($data["description"]);
136  $this->setNrOfTries($data['nr_of_tries']);
137  $this->setSuggestedSolution($data["solution_hint"]);
138  $this->setOriginalId($data["original_id"]);
139  $this->setObjId($data["obj_fi"]);
140  $this->setAuthor($data["author"]);
141  $this->setOwner($data["owner"]);
142  $this->setPoints($data["points"]);
143 
144  include_once("./Services/RTE/classes/class.ilRTE.php");
145  $this->setQuestion(ilRTE::_replaceMediaObjectImageSrc($data["question_text"], 1));
146  $this->setEstimatedWorkingTime(substr($data["working_time"], 0, 2), substr($data["working_time"], 3, 2), substr($data["working_time"], 6, 2));
147  $this->setMaxSize($data["maxsize"]);
148  $this->setAllowedExtensions($data["allowedextensions"]);
149  $this->setCompletionBySubmission($data['compl_by_submission'] == 1 ? true : false);
150  }
151  parent::loadFromDb($question_id);
152  }
153 
157  public function duplicate($for_test = true, $title = "", $author = "", $owner = "", $testObjId = null)
158  {
159  if ($this->id <= 0)
160  {
161  // The question has not been saved. It cannot be duplicated
162  return;
163  }
164  // duplicate the question in database
165  $this_id = $this->getId();
166 
167  if( (int)$testObjId > 0 )
168  {
169  $thisObjId = $this->getObjId();
170  }
171 
172  $clone = $this;
173  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
175  $clone->id = -1;
176 
177  if( (int)$testObjId > 0 )
178  {
179  $clone->setObjId($testObjId);
180  }
181 
182  if ($title)
183  {
184  $clone->setTitle($title);
185  }
186 
187  if ($author)
188  {
189  $clone->setAuthor($author);
190  }
191  if ($owner)
192  {
193  $clone->setOwner($owner);
194  }
195 
196  if ($for_test)
197  {
198  $clone->saveToDb($original_id);
199  }
200  else
201  {
202  $clone->saveToDb();
203  }
204 
205  // copy question page content
206  $clone->copyPageOfQuestion($this_id);
207  // copy XHTML media objects
208  $clone->copyXHTMLMediaObjectsOfQuestion($this_id);
209  // duplicate the generic feedback
210  $clone->duplicateFeedbackGeneric($this_id);
211 
212  $clone->onDuplicate($thisObjId, $this_id, $clone->getObjId(), $clone->getId());
213 
214  return $clone->id;
215  }
216 
220  public function copyObject($target_questionpool, $title = "")
221  {
222  if ($this->id <= 0)
223  {
224  // The question has not been saved. It cannot be duplicated
225  return;
226  }
227  // duplicate the question in database
228  $clone = $this;
229  include_once ("./Modules/TestQuestionPool/classes/class.assQuestion.php");
231  $clone->id = -1;
232  $source_questionpool = $this->getObjId();
233  $clone->setObjId($target_questionpool);
234  if ($title)
235  {
236  $clone->setTitle($title);
237  }
238  $clone->saveToDb();
239 
240  // copy question page content
241  $clone->copyPageOfQuestion($original_id);
242  // copy XHTML media objects
243  $clone->copyXHTMLMediaObjectsOfQuestion($original_id);
244  // duplicate the generic feedback
245  $clone->duplicateFeedbackGeneric($original_id);
246 
247  $clone->onCopy($this->getObjId(), $this->getId());
248 
249  return $clone->id;
250  }
251 
257  public function getMaximumPoints()
258  {
259  return $this->getPoints();
260  }
261 
270  public function calculateReachedPoints($active_id, $pass = NULL)
271  {
272  global $ilDB;
273 
274  if (is_null($pass))
275  {
276  $pass = $this->getSolutionMaxPass($active_id);
277  }
278  $points = 0;
279  $points = parent::calculateReachedPoints($active_id, $pass = NULL, $points);
280  return $points;
281  }
282 
288  function checkUpload()
289  {
290  $this->lng->loadLanguageModule("form");
291  // remove trailing '/'
292  while (substr($_FILES["upload"]["name"],-1) == '/')
293  {
294  $_FILES["upload"]["name"] = substr($_FILES["upload"]["name"],0,-1);
295  }
296 
297  $filename = $_FILES["upload"]["name"];
298  $filename_arr = pathinfo($_FILES["upload"]["name"]);
299  $suffix = $filename_arr["extension"];
300  $mimetype = $_FILES["upload"]["type"];
301  $size_bytes = $_FILES["upload"]["size"];
302  $temp_name = $_FILES["upload"]["tmp_name"];
303  $error = $_FILES["upload"]["error"];
304 
305  if ($size_bytes > $this->getMaxFilesizeInBytes())
306  {
307  ilUtil::sendInfo($this->lng->txt("form_msg_file_size_exceeds"), true);
308  return false;
309  }
310 
311  // error handling
312  if ($error > 0)
313  {
314  switch ($error)
315  {
316  case UPLOAD_ERR_INI_SIZE:
317  ilUtil::sendInfo($this->lng->txt("form_msg_file_size_exceeds"), true);
318  return false;
319  break;
320 
321  case UPLOAD_ERR_FORM_SIZE:
322  ilUtil::sendInfo($this->lng->txt("form_msg_file_size_exceeds"), true);
323  return false;
324  break;
325 
326  case UPLOAD_ERR_PARTIAL:
327  ilUtil::sendInfo($this->lng->txt("form_msg_file_partially_uploaded"), true);
328  return false;
329  break;
330 
331  case UPLOAD_ERR_NO_FILE:
332  ilUtil::sendInfo($this->lng->txt("form_msg_file_no_upload"), true);
333  return false;
334  break;
335 
336  case UPLOAD_ERR_NO_TMP_DIR:
337  ilUtil::sendInfo($this->lng->txt("form_msg_file_missing_tmp_dir"), true);
338  return false;
339  break;
340 
341  case UPLOAD_ERR_CANT_WRITE:
342  ilUtil::sendInfo($this->lng->txt("form_msg_file_cannot_write_to_disk"), true);
343  return false;
344  break;
345 
346  case UPLOAD_ERR_EXTENSION:
347  ilUtil::sendInfo($this->lng->txt("form_msg_file_upload_stopped_ext"), true);
348  return false;
349  break;
350  }
351  }
352 
353  // check suffixes
354  if (strlen($suffix) && count($this->getAllowedExtensionsArray()))
355  {
356  if (!in_array(strtolower($suffix), $this->getAllowedExtensionsArray()))
357  {
358  ilUtil::sendInfo($this->lng->txt("form_msg_file_wrong_file_type"), true);
359  return false;
360  }
361  }
362 
363  // virus handling
364  if (strlen($temp_name))
365  {
366  $vir = ilUtil::virusHandling($temp_name, $filename);
367  if ($vir[0] == false)
368  {
369  ilUtil::sendInfo($this->lng->txt("form_msg_file_virus_found")."<br />".$vir[1], true);
370  return false;
371  }
372  }
373  return true;
374  }
375 
379  protected function getFileUploadPath($test_id, $active_id, $question_id = null)
380  {
381  if (is_null($question_id)) $question_id = $this->getId();
382  return CLIENT_WEB_DIR . "/assessment/tst_$test_id/$active_id/$question_id/files/";
383  }
384 
390  function getFileUploadPathWeb($test_id, $active_id, $question_id = null)
391  {
392  if (is_null($question_id)) $question_id = $this->getId();
393  include_once "./Services/Utilities/classes/class.ilUtil.php";
394  $webdir = ilUtil::removeTrailingPathSeparators(CLIENT_WEB_DIR) . "/assessment/tst_$test_id/$active_id/$question_id/files/";
396  }
397 
403  public function getUploadedFiles($active_id, $pass = null)
404  {
405  global $ilDB;
406  if (is_null($pass))
407  {
408  $pass = $this->getSolutionMaxPass($active_id);
409  }
410  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE active_fi = %s AND question_fi = %s AND pass = %s ORDER BY tstamp",
411  array("integer", "integer", "integer"),
412  array($active_id, $this->getId(), $pass)
413  );
414  $found = array();
415  while ($data = $ilDB->fetchAssoc($result))
416  {
417  array_push($found, $data);
418  }
419  return $found;
420  }
421 
427  public function getUploadedFilesForWeb($active_id, $pass)
428  {
429  global $ilDB;
430 
431  $found = $this->getUploadedFiles($active_id, $pass);
432  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
433  array('integer'),
434  array($active_id)
435  );
436  if ($result->numRows() == 1)
437  {
438  $row = $ilDB->fetchAssoc($result);
439  $test_id = $row["test_fi"];
440  $path = $this->getFileUploadPathWeb($test_id, $active_id);
441  foreach ($found as $idx => $data)
442  {
443  $found[$idx]['webpath'] = $path;
444  }
445  }
446  return $found;
447  }
448 
454  protected function deleteUploadedFiles($files, $test_id, $active_id)
455  {
456  global $ilDB;
457 
458  $pass = null;
459  $active_id = null;
460  foreach ($files as $solution_id)
461  {
462  $result = $ilDB->queryF("SELECT * FROM tst_solutions WHERE solution_id = %s",
463  array("integer"),
464  array($solution_id)
465  );
466  if ($result->numRows() == 1)
467  {
468  $data = $ilDB->fetchAssoc($result);
469  $pass = $data['pass'];
470  $active_id = $data['active_fi'];
471  @unlink($this->getFileUploadPath($test_id, $active_id) . $data['value1']);
472  }
473  }
474  foreach ($files as $solution_id)
475  {
476  $affectedRows = $ilDB->manipulateF("DELETE FROM tst_solutions WHERE solution_id = %s",
477  array("integer"),
478  array($solution_id)
479  );
480  }
481  }
482 
488  public function getMaxFilesizeAsString()
489  {
490  $size = $this->getMaxFilesizeInBytes();
491  if ($size < 1024)
492  {
493  $max_filesize = sprintf("%.1f Bytes",$size);
494  }
495  else if ($size < 1024*1024)
496  {
497  $max_filesize = sprintf("%.1f KB",$size/1024);
498  }
499  else
500  {
501  $max_filesize = sprintf("%.1f MB",$size/1024/1024);
502  }
503 
504  return $max_filesize;
505  }
506 
512  public function getMaxFilesizeInBytes()
513  {
514  if (strlen($this->getMaxSize()))
515  {
516  return $this->getMaxSize();
517  }
518  else
519  {
520  // get the value for the maximal uploadable filesize from the php.ini (if available)
521  $umf = get_cfg_var("upload_max_filesize");
522  // get the value for the maximal post data from the php.ini (if available)
523  $pms = get_cfg_var("post_max_size");
524 
525  //convert from short-string representation to "real" bytes
526  $multiplier_a=array("K"=>1024, "M"=>1024*1024, "G"=>1024*1024*1024);
527 
528  $umf_parts=preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
529  $pms_parts=preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
530 
531  if (count($umf_parts) == 2) { $umf = $umf_parts[0]*$multiplier_a[$umf_parts[1]]; }
532  if (count($pms_parts) == 2) { $pms = $pms_parts[0]*$multiplier_a[$pms_parts[1]]; }
533 
534  // use the smaller one as limit
535  $max_filesize = min($umf, $pms);
536 
537  if (!$max_filesize) $max_filesize=max($umf, $pms);
538  return $max_filesize;
539  }
540  }
541 
549  public function saveWorkingData($active_id, $pass = NULL)
550  {
551  global $ilDB;
552  global $ilUser;
553 
554  if (is_null($pass))
555  {
556  include_once "./Modules/Test/classes/class.ilObjTest.php";
557  $pass = ilObjTest::_getPass($active_id);
558  }
559 
560  $result = $ilDB->queryF("SELECT test_fi FROM tst_active WHERE active_id = %s",
561  array('integer'),
562  array($active_id)
563  );
564  $test_id = 0;
565  if ($result->numRows() == 1)
566  {
567  $row = $ilDB->fetchAssoc($result);
568  $test_id = $row["test_fi"];
569  }
570 
571  $entered_values = false;
572  if (strcmp($_POST['cmd']['gotoquestion'], $this->lng->txt('delete')) == 0)
573  {
574  $deletefiles = $_POST['file'];
575  if (is_array($deletefiles) && count($deletefiles) > 0)
576  {
577  $this->deleteUploadedFiles($deletefiles, $test_id, $active_id);
578  }
579  else
580  {
581  ilUtil::sendInfo($this->lng->txt('no_checkbox'), true);
582  }
583  }
584  else
585  {
586  if (strlen($_FILES["upload"]["tmp_name"]))
587  {
588  if ($this->checkUpload())
589  {
590  if (!@file_exists($this->getFileUploadPath($test_id, $active_id))) ilUtil::makeDirParents($this->getFileUploadPath($test_id, $active_id));
591  $version = time();
592  $filename_arr = pathinfo($_FILES["upload"]["name"]);
593  $extension = $filename_arr["extension"];
594  $newfile = "file_" . $active_id . "_" . $pass . "_" . $version . "." . $extension;
595  ilUtil::moveUploadedFile($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"], $this->getFileUploadPath($test_id, $active_id) . $newfile);
596  $next_id = $ilDB->nextId('tst_solutions');
597  $affectedRows = $ilDB->insert("tst_solutions", array(
598  "solution_id" => array("integer", $next_id),
599  "active_fi" => array("integer", $active_id),
600  "question_fi" => array("integer", $this->getId()),
601  "value1" => array("clob", $newfile),
602  "value2" => array("clob", $_FILES['upload']['name']),
603  "pass" => array("integer", $pass),
604  "tstamp" => array("integer", time())
605  ));
606  $entered_values = true;
607  }
608  }
609  }
610  if ($entered_values)
611  {
612  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
614  {
615  $this->logAction($this->lng->txtlng("assessment", "log_user_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
616  }
617  }
618  else
619  {
620  include_once ("./Modules/Test/classes/class.ilObjAssessmentFolder.php");
622  {
623  $this->logAction($this->lng->txtlng("assessment", "log_user_not_entered_values", ilObjAssessmentFolder::_getLogLanguage()), $active_id, $this->getId());
624  }
625  }
626  parent::saveWorkingData($active_id, $pass);
627 
628  $this->handleSubmission($active_id, $pass);
629 
630  return true;
631  }
632 
644  protected function handleSubmission($active_id, $pass)
645  {
646  global $ilObjDataCache;
647 
649  {
650  $maxpoints = assQuestion::_getMaximumPoints($this->getId());
651 
652  if($this->getUploadedFiles($active_id, $pass))
653  {
654  $points = $maxpoints;
655  }
656  else
657  {
658  $points = 0;
659  }
660 
661  assQuestion::_setReachedPoints($active_id, $this->getId(), $points, $maxpoints, $pass, 1);
662 
663  // update learning progress
664  include_once 'Modules/Test/classes/class.ilObjTestAccess.php';
665  include_once 'Services/Tracking/classes/class.ilLPStatusWrapper.php';
667  ilObjTest::_getObjectIDFromActiveID((int)$active_id),
668  ilObjTestAccess::_getParticipantId((int) $active_id)
669  );
670  }
671  }
672 
678  public function getQuestionType()
679  {
680  return "assFileUpload";
681  }
682 
688  public function getAdditionalTableName()
689  {
690  return "qpl_qst_fileupload";
691  }
692 
698  public function getAnswerTableName()
699  {
700  return "";
701  }
702 
708  public function deleteAnswers($question_id)
709  {
710  }
711 
716  public function getRTETextWithMediaObjects()
717  {
719  return $text;
720  }
721 
733  public function setExportDetailsXLS(&$worksheet, $startrow, $active_id, $pass, &$format_title, &$format_bold)
734  {
735  include_once ("./Services/Excel/classes/class.ilExcelUtils.php");
736  $worksheet->writeString($startrow, 0, ilExcelUtils::_convert_text($this->lng->txt($this->getQuestionType())), $format_title);
737  $worksheet->writeString($startrow, 1, ilExcelUtils::_convert_text($this->getTitle()), $format_title);
738  $i = 1;
739  $solutions = $this->getSolutionValues($active_id, $pass);
740  foreach ($solutions as $solution)
741  {
742  $worksheet->writeString($startrow + $i, 0, ilExcelUtils::_convert_text($this->lng->txt("result")), $format_bold);
743  if (strlen($solution["value1"]))
744  {
745  $worksheet->write($startrow + $i, 1, ilExcelUtils::_convert_text($solution["value1"]));
746  $worksheet->write($startrow + $i, 2, ilExcelUtils::_convert_text($solution["value2"]));
747  }
748  $i++;
749  }
750  return $startrow + $i + 1;
751  }
752 
765  public function fromXML(&$item, &$questionpool_id, &$tst_id, &$tst_object, &$question_counter, &$import_mapping)
766  {
767  include_once "./Modules/TestQuestionPool/classes/import/qti12/class.assFileUploadImport.php";
768  $import = new assFileUploadImport($this);
769  $import->fromXML($item, $questionpool_id, $tst_id, $tst_object, $question_counter, $import_mapping);
770  }
771 
778  public function toXML($a_include_header = true, $a_include_binary = true, $a_shuffle = false, $test_output = false, $force_image_references = false)
779  {
780  include_once "./Modules/TestQuestionPool/classes/export/qti12/class.assFileUploadExport.php";
781  $export = new assFileUploadExport($this);
782  return $export->toXML($a_include_header, $a_include_binary, $a_shuffle, $test_output, $force_image_references);
783  }
784 
790  public function getBestSolution($active_id, $pass)
791  {
792  $user_solution = array();
793  return $user_solution;
794  }
795 
801  public function getMaxSize()
802  {
803  return $this->maxsize;
804  }
805 
811  public function setMaxSize($a_value)
812  {
813  $this->maxsize = $a_value;
814  }
815 
821  public function getAllowedExtensionsArray()
822  {
823  if (strlen($this->allowedextensions))
824  {
825  return split(",", $this->allowedextensions);
826  }
827  return array();
828  }
829 
835  public function getAllowedExtensions()
836  {
838  }
839 
845  public function setAllowedExtensions($a_value)
846  {
847  $this->allowedextensions = strtolower(trim($a_value));
848  }
849 
853  public function __get($value)
854  {
855  switch ($value)
856  {
857  case "maxsize":
858  return $this->getMaxSize();
859  break;
860  case "allowedextensions":
861  return $this->getAllowedExtensions();
862  break;
863  case 'completion_by_submission':
864  return $this->isCompletionBySubmissionEnabled();
865  break;
866  default:
867  return parent::__get($value);
868  break;
869  }
870  }
871 
875  public function __set($key, $value)
876  {
877  switch ($key)
878  {
879  case "maxsize":
880  $this->setMaxSize($value);
881  break;
882  case "allowedextensions":
883  $this->setAllowedExtensions($value);
884  break;
885  case 'completion_by_submission':
886  $this->setCompletionBySubmission($value);
887  break;
888  default:
889  parent::__set($key, $value);
890  break;
891  }
892  }
893 
899  public function hasFileUploads($test_id)
900  {
901  global $ilDB;
902  $result = $ilDB->queryF("
903  SELECT tst_solutions.solution_id
904  FROM tst_solutions, tst_active, qpl_questions
905  WHERE tst_solutions.active_fi = tst_active.active_id
906  AND tst_solutions.question_fi = qpl_questions.question_id
907  AND qpl_questions.question_id = %s
908  AND tst_active.test_fi = %s
909  ",
910  array("integer", "integer"),
911  array($this->getId(), $test_id)
912  );
913  if ($result->numRows() > 0)
914  {
915  return true;
916  }
917  else
918  {
919  return false;
920  }
921  }
922 
926  public function getFileUploadZIPFile($test_id)
927  {
929  global $ilDB;
930  $query = "
931  SELECT
932  tst_solutions.solution_id, tst_solutions.pass, tst_solutions.active_fi, tst_solutions.question_fi,
933  tst_solutions.value1, tst_solutions.value2, tst_solutions.tstamp
934  FROM tst_solutions, tst_active, qpl_questions
935  WHERE tst_solutions.active_fi = tst_active.active_id
936  AND tst_solutions.question_fi = qpl_questions.question_id
937  AND tst_solutions.question_fi = %s
938  AND tst_active.test_fi = %s
939  ORDER BY tst_solutions.active_fi, tst_solutions.tstamp";
940 
941  $result = $ilDB->queryF( $query,
942  array("integer", "integer"),
943  array($this->getId(), $test_id)
944  );
945 
946  $zipfile = ilUtil::ilTempnam() . ".zip";
947  $tempdir = ilUtil::ilTempnam();
948  if ($result->numRows())
949  {
950  $userdata = array();
951  $data .= "<html><head>";
952  $data .= '<meta http-equiv="content-type" content="text/html; charset=UTF-8" />';
953  $data .= '<style>
954  table { border: 1px #333 solid; border-collapse:collapse;}
955  td, th { border: 1px #333 solid; padding: 0.25em;}
956  th { color: #fff; background-color: #666;}
957  </style>
958  ';
959  $data .= "<title>" . $this->getTitle() . "</title></head><body>\n";
960  $data .= "<h1>" . $this->getTitle() . "</h1>\n";
961  $data .= "<table><thead>\n";
962  $data .= "<tr><th>" . $this->lng->txt("name") . "</th><th>" . $this->lng->txt("filename") . "</th><th>" . $this->lng->txt("pass") . "</th><th>" . $this->lng->txt("location") . "</th><th>" . $this->lng->txt("date") . "</th></tr></thead><tbody>\n";
963  while ($row = $ilDB->fetchAssoc($result))
964  {
965  ilUtil::makeDirParents($tempdir . "/" . $row["active_fi"]."/".$row["question_fi"]);
966  @copy($this->getFileUploadPath($test_id, $row["active_fi"], $row["question_fi"]) . $row["value1"], $tempdir . "/" . $row["active_fi"]."/".$row["question_fi"] . "/" . $row["value1"]);
967  if (!array_key_exists($row["active_fi"], $userdata))
968  {
969  include_once "./Modules/Test/classes/class.ilObjTestAccess.php";
970  $userdata[$row["active_fi"]] = ilObjTestAccess::_getParticipantData($row["active_fi"]);
971  }
972  $data .= "<tr><td>".$userdata[$row["active_fi"]]."</td><td><a href=\"".$row["active_fi"]."/".$row["question_fi"]."/".$row["value1"]."\" target=\"_blank\">".$row["value2"]."</a></td><td>".$row["pass"]."</td><td>".$row["active_fi"]."/".$row["question_fi"]."/".$row["value1"]."</td>";
973  $data .= "<td>" . ilFormat::fmtDateTime(ilFormat::unixtimestamp2datetime($row["tstamp"]), $this->lng->txt("lang_dateformat"), $this->lng->txt("lang_timeformat"), "datetime", FALSE) . "</td>";
974  $data .= "</tr>\n";
975  }
976  $data .= "</tbody></table>\n";
977  $data .= "</body></html>\n";
978 
979  $indexfile = $tempdir . "/index.html";
980  $fh = fopen($indexfile, 'w');
981  fwrite($fh, $data);
982  fclose($fh);
983  }
984  ilUtil::zip($tempdir, $zipfile);
985  ilUtil::delDir($tempdir);
986  ilUtil::deliverFile($zipfile, ilUtil::getASCIIFilename($this->getTitle().".zip"), "application/zip", false, true);
987  }
988 
998  {
1000  }
1001 
1011  public function setCompletionBySubmission($bool)
1012  {
1013  $this->completion_by_submission = (bool)$bool;
1014  return $this;
1015  }
1016 }
1017 
1018 ?>