ILIAS  trunk Revision v11.0_alpha-1723-g8e69f309bab
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
class.ilAssFileUploadUploadsExporter.php
Go to the documentation of this file.
1 <?php
2 
20 
28 {
29  public const ZIP_FILE_MIME_TYPE = 'application/zip';
30  public const ZIP_FILE_EXTENSION = '.zip';
32  private \ILIAS\ResourceStorage\Services $irss;
33  private \ILIAS\Filesystem\Util\Archive\Archives $archive;
34  private \ILIAS\FileDelivery\Services $file_delivery;
35 
39  private $test_title;
40 
44  private $question;
45 
50 
55 
59  private $tempDirPath;
60 
64  private $mainFolderName;
65 
69  public function __construct(
70  private ilDBInterface $db,
71  private ilLanguage $lng,
72  private int $ref_id,
73  private int $test_id,
74  ) {
75  global $DIC;
76  $f = new ilTestParticipantAccessFilterFactory($DIC->access());
77  $this->access_filter = $f->getAccessStatisticsUserFilter($this->ref_id);
78 
79  $this->irss = $DIC->resourceStorage();
80  $this->archive = $DIC->archives();
81  $this->file_delivery = $DIC->fileDelivery();
82  }
83 
84  public function getRefId(): int
85  {
86  return $this->ref_id;
87  }
88 
89 
90  public function getTestId(): int
91  {
92  return $this->test_id;
93  }
94 
95 
99  public function getTestTitle(): string
100  {
101  return $this->test_title;
102  }
103 
104 
105  public function setTestTitle(string $test_title): void
106  {
107  $this->test_title = $test_title;
108  }
109 
114  {
115  return $this->question;
116  }
117 
121  public function setQuestion($question): void
122  {
123  $this->question = $question;
124  }
125 
126  public function buildAndDownload(): void
127  {
128  $solution_data = $this->getFileUploadSolutionData();
129 
130  $participant_data = $this->getParticipantData($solution_data);
131 
132  $this->collectUploadedFiles($solution_data, $participant_data);
133  }
134 
135  private function initFilenames(): void
136  {
137  $this->tempDirPath = ilFileUtils::ilTempnam();
138 
139  $this->tempZipFilePath = ilFileUtils::ilTempnam($this->tempDirPath) . self::ZIP_FILE_EXTENSION;
140 
141  $this->mainFolderName = ilFileUtils::getASCIIFilename(
142  str_replace(' ', '', $this->getTestTitle() . '_' . $this->question->getTitle())
143  );
144  }
145 
146  private function getFileUploadSolutionData(): array
147  {
148  $query = "
149  SELECT tst_solutions.solution_id, tst_solutions.pass, tst_solutions.active_fi, tst_solutions.question_fi,
150  tst_solutions.value1, tst_solutions.value2, tst_solutions.tstamp
151  FROM tst_solutions, tst_active, qpl_questions
152  WHERE tst_solutions.active_fi = tst_active.active_id
153  AND tst_solutions.question_fi = qpl_questions.question_id
154  AND tst_solutions.question_fi = %s
155  AND tst_active.test_fi = %s
156  ORDER BY tst_solutions.active_fi, tst_solutions.tstamp
157  ";
158 
159  $res = $this->db->queryF(
160  $query,
161  ["integer", "integer"],
162  [$this->question->getId(), $this->getTestId()]
163  );
164 
165  $solutionData = [];
166 
167  while ($row = $this->db->fetchAssoc($res)) {
168  if (!isset($solutionData[$row['active_fi']])) {
169  $solutionData[ $row['active_fi'] ] = [];
170  }
171 
172  if (!isset($solutionData[ $row['active_fi'] ][ $row['pass'] ])) {
173  $solutionData[ $row['active_fi'] ][ $row['pass'] ] = [];
174  }
175 
176  $solutionData[ $row['active_fi'] ][ $row['pass'] ][] = $row;
177  }
178 
179  return $solutionData;
180  }
181 
182  private function getParticipantData($solutionData): ilTestParticipantData
183  {
184  $activeIds = [];
185 
186  foreach ($solutionData as $activeId => $passes) {
187  $activeIds[] = $activeId;
188  }
189 
190  $participantData = new ilTestParticipantData($this->db, $this->lng);
191  $participantData->setActiveIdsFilter($activeIds);
192  $participantData->setParticipantAccessFilter($this->access_filter);
193  $participantData->load($this->getTestId());
194 
195  return $participantData;
196  }
197 
198  private function collectUploadedFiles(array $solution_data, ilTestParticipantData $participant_data): void
199  {
200  $streams = [];
201 
202  foreach ($solution_data as $activeId => $passes) {
203  if (!in_array($activeId, $participant_data->getActiveIds(), true)) {
204  continue;
205  }
206 
207  foreach ($passes as $pass => $files) {
208  foreach ($files as $file) {
209  // path inside zip
210  $dir = $this->mainFolderName;
211  $dir .= $participant_data->getFileSystemCompliantFullnameByActiveId($activeId) . '/';
212  $dir .= $this->getPassSubDirName($file['pass']) . '/';
213 
214  // IRSS Version
215  if ($file['value2'] === 'rid') {
216  $revision = $this->irss->manage()->getCurrentRevision(
217  $rid = $this->irss->manage()->find($file['value1'])
218  );
219  $streams[$dir . $revision->getTitle()] = $this->irss->consume()->stream($rid)->getStream();
220  continue;
221  }
222 
223  // Legacy Version
224  $file_dir = $this->question->getFileUploadPath(
225  $this->getTestId(),
226  $activeId,
227  $this->question->getId()
228  );
229 
230  $legacy_file_path = $file_dir . $file['value1'];
231  if (!is_file($legacy_file_path)) {
232  continue;
233  }
234 
235  $streams[$dir . $file['value2']] = Streams::ofResource(fopen($legacy_file_path, 'rb'));
236  }
237  }
238  }
239 
240  $zip = $this->archive->zip($streams);
241 
242  $this->file_delivery->delivery()->attached(
243  $zip->get(),
244  $this->getDispoZipFileName(),
245  'application/zip'
246  );
247  }
248 
249  private function getPassSubDirName($pass): string
250  {
251  return $this->lng->txt('pass') . '_' . ($pass + 1);
252  }
253 
254  private function createFileUploadCollectionZipFile(): void
255  {
256  ilFileUtils::zip($this->tempDirPath . '/' . $this->mainFolderName, $this->tempZipFilePath);
257 
258  $pathinfo = pathinfo($this->tempZipFilePath);
259  $this->finalZipFilePath = dirname($pathinfo['dirname']) . '/' . $pathinfo['basename'];
260 
261  try {
262  ilFileUtils::rename($this->tempZipFilePath, $this->finalZipFilePath);
263  } catch (\ilFileUtilsException $e) {
264  \ilLoggerFactory::getRootLogger()->error($e->getMessage());
265  }
266  }
267 
268  public function getFinalZipFilePath(): string
269  {
271  }
272 
273  public function getDispoZipFileName(): string
274  {
276  $this->test_title . '_' . $this->question->getTitle() . self::ZIP_FILE_EXTENSION
277  );
278  }
279 
280  public function getZipFileMimeType(): string
281  {
282  return self::ZIP_FILE_MIME_TYPE;
283  }
284 }
$res
Definition: ltiservices.php:66
__construct(private ilDBInterface $db, private ilLanguage $lng, private int $ref_id, private int $test_id,)
ILIAS Filesystem Util Archive Archives $archive
collectUploadedFiles(array $solution_data, ilTestParticipantData $participant_data)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
static getASCIIFilename(string $a_filename)
$ref_id
Definition: ltiauth.php:65
global $DIC
Definition: shib_login.php:22
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
global $lng
Definition: privfeed.php:31
static zip(string $a_dir, string $a_file, bool $compress_content=false)
static rename(string $a_source, string $a_target)
static getRootLogger()
The unique root logger has a fixed error level.
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...