Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
AttachmentFiles
0.00% covered (danger)
0.00%
0 / 55
0.00% covered (danger)
0.00%
0 / 5
156
0.00% covered (danger)
0.00%
0 / 1
 importFiles
0.00% covered (danger)
0.00%
0 / 20
0.00% covered (danger)
0.00%
0 / 1
6
 deleteFile
0.00% covered (danger)
0.00%
0 / 18
0.00% covered (danger)
0.00%
0 / 1
20
 testDAO
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getAttachmentFilePath
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
12
 stringifyDataChunk
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/** @noinspection PhpUnhandledExceptionInspection */
3declare(strict_types=1);
4// TODO unit-test
5
6class AttachmentFiles {
7  protected static $_testDAO;
8
9  public static function importFiles(int $workspaceId, array $uploadedFiles, Attachment $attachment, string $type): void {
10    $workspace = new Workspace($workspaceId);
11    $workspacePath = $workspace->getWorkspacePath();
12
13    $dataParts = [];
14    foreach ($uploadedFiles as $originalFileName) {
15      $dst = "$workspacePath/UnitAttachments/";
16      Folder::createPath($dst);
17      $attachmentCode = Random::string(32, false);
18      $extension = FileExt::get($originalFileName);
19      $attachmentFileId = "$type:$attachmentCode.$extension";
20      copy("$workspacePath/$originalFileName", "$dst/$attachmentCode.$extension");
21      unlink("$workspacePath/$originalFileName");
22      $attachmentFileIds = [...$attachment->attachmentFileIds, $attachmentFileId];
23      $dataParts[$attachment->attachmentId] = self::stringifyDataChunk($attachment->variableId, $attachmentFileIds);
24    }
25
26    self::testDAO()->updateDataParts(
27      $attachment->_testId,
28      $attachment->_unitName,
29      $dataParts,
30      'iqb-standard@1.0',
31      TimeStamp::now() * 1000 // unit_data.last_modified normally expects CLIENT-side timestamps in ms
32    );
33  }
34
35  public static function deleteFile(int $workspaceId, string $attachmentFileId, Attachment $attachment): void {
36    $attachmentFileIds = $attachment->attachmentFileIds;
37    if (!in_array($attachmentFileId, $attachmentFileIds)) {
38      throw new HttpError("File `$attachmentFileId` not found in attachment `$attachment->attachmentId`.", 404);
39    }
40    array_splice($attachmentFileIds, array_search($attachmentFileId, $attachmentFileIds), 1);
41
42    $dataParts = [];
43    $dataParts[$attachment->attachmentId] = self::stringifyDataChunk($attachment->variableId, $attachmentFileIds);
44
45    if (count($attachmentFileIds)) {
46      self::testDAO()->updateDataParts(
47        $attachment->_testId,
48        $attachment->_unitName,
49        $dataParts,
50        'iqb-standard@1.0',
51        TimeStamp::now() * 1000 // unit_data.last_modified normally expects CLIENT-side timestamps in ms
52      );
53
54    } else {
55      self::testDAO()->deleteAttachmentDataPart($attachment->attachmentId);
56    }
57
58    $filePath = self::getAttachmentFilePath($workspaceId, $attachmentFileId, $attachment);
59    if (!file_exists($filePath)) {
60      unlink($filePath);
61    }
62  }
63
64  protected static function testDAO(): TestDAO {
65    if (!self::$_testDAO) {
66      self::$_testDAO = new TestDAO();
67    }
68
69    return self::$_testDAO;
70  }
71
72  public static function getAttachmentFilePath(int $workspaceId, string $attachmentFileId, Attachment $attachment): string {
73    list($dataType, $fileName) = explode(':', $attachmentFileId);
74    if (!in_array($attachmentFileId, $attachment->attachmentFileIds)) {
75      throw new HttpError("AttachmentId `$attachmentFileId` not found in attachment `$attachment->attachmentId`", 404);
76    }
77
78    $filePath = DATA_DIR . "/ws_$workspaceId/UnitAttachments/$fileName";
79
80    if (!file_exists($filePath)) {
81      throw new HttpError("File not found:`$attachment->attachmentId`", 404);
82    }
83
84    return $filePath;
85  }
86
87  private static function stringifyDataChunk(string $variableId, array $attachmentIds): string {
88    return json_encode([
89      [
90        "id" => $variableId,
91        "value" => $attachmentIds,
92        "status" => 'VALUE_CHANGED'
93      ]
94    ]);
95  }
96
97}