ILIAS  release_8 Revision v8.24
class.ilCollectFilesJob.php
Go to the documentation of this file.
1<?php
23
31{
32 private ?ilLogger $logger;
38 private static array $targets = [];
39
43 public function __construct()
44 {
45 global $DIC;
46 $this->logger = $DIC->logger()->cal();
47 }
48
49
53 public function getInputTypes(): array
54 {
55 return
56 [
57 new SingleType(ilCopyDefinition::class),
58 new SingleType(BooleanValue::class),
59 ];
60 }
61
62
66 public function getOutputType(): Type
67 {
68 return new SingleType(ilCopyDefinition::class);
69 }
70
71
75 public function isStateless(): bool
76 {
77 return true;
78 }
79
80
85 public function run(array $input, \ILIAS\BackgroundTasks\Observer $observer): Value
86 {
87 $this->logger->debug('Start collecting files!');
88 $this->logger->dump($input);
89 $definition = $input[0];
90 $initiated_by_folder_action = $input[1]->getValue();
91 $object_ref_ids = $definition->getObjectRefIds();
92 $files = array();
93
94 foreach ($object_ref_ids as $object_ref_id) {
95 $object = ilObjectFactory::getInstanceByRefId($object_ref_id);
96 $object_type = $object->getType();
97 $object_name = $object->getTitle();
98 $object_temp_dir = ""; // empty as content will be added in recurseFolder and getFileDirs
99
100 if ($object_type == "fold") {
101 $num_recursions = 0;
102 $files_from_folder = self::recurseFolder($object_ref_id, $object_name, $object_temp_dir, $num_recursions, $initiated_by_folder_action);
103 $files = array_merge($files, $files_from_folder);
104 } elseif (($object_type == "file") && (($file_dirs = self::getFileDirs(
105 $object_ref_id,
106 $object_name,
107 $object_temp_dir
108 )) !== false)) {
109 $files[] = $file_dirs;
110 }
111 }
112 $this->logger->debug('Collected files:');
113 $this->logger->dump($files);
114
115 $num_files = 0;
116 foreach ($files as $file) {
117 $definition->addCopyDefinition($file['source_dir'], $file['target_dir']);
118 $this->logger->debug('Added new copy definition: ' . $file['source_dir'] . ' -> ' . $file['target_dir']);
119
120 // count files only (without empty directories)
121 $is_empty_folder = preg_match_all("/\/$/", $file['target_dir']);
122 if (!$is_empty_folder) {
123 $num_files++;
124 }
125 }
126 $definition->setObjectRefIds($object_ref_ids);
127 $definition->setNumFiles($num_files);
128
129 return $definition;
130 }
131
132
139 private static function getFileDirs($a_ref_id, $a_file_name, $a_temp_dir)
140 {
141 global $DIC;
142
143 $user = $DIC->user();
144 $ilAccess = $DIC->access();
145 if ($ilAccess->checkAccessOfUser($user->getId(), "read", "", $a_ref_id)) {
146 $file = new ilObjFile($a_ref_id);
147 $source_dir = $file->getFile();
148 if (@!is_file($source_dir)) {
149 return false;
150 }
151 $target_dir = $a_temp_dir . '/' . ilFileUtils::getASCIIFilename($a_file_name);
152
153 // #25025: allow duplicate filenames by appending an incrementing
154 // number per duplicate in brackets to the name.
155 // Example: test.txt, test (1).txt, test (2).txt, ...
156 if (isset(self::$targets[$target_dir])) {
157 $target_info = pathinfo($target_dir);
158 $filename = $target_info["filename"];
159 $extension = isset($target_info["extension"]) ? "." . $target_info["extension"] : "";
160 $target_dir = $a_temp_dir . $filename . " (" . ++self::$targets[$target_dir] . ")" . $extension;
161 } else {
162 self::$targets[$target_dir] = 0;
163 }
164
165 return [
166 "source_dir" => $source_dir,
167 "target_dir" => $target_dir,
168 ];
169 }
170
171 return false;
172 }
173
174
182 private static function recurseFolder($a_ref_id, $a_folder_name, $a_temp_dir, $a_num_recursions, $a_initiated_by_folder_action): array
183 {
184 global $DIC;
185
186 $num_recursions = $a_num_recursions + 1;
187 $tree = $DIC->repositoryTree();
188 $ilAccess = $DIC->access();
189 $files = array();
190
191 // Avoid the duplication of the uppermost folder when the download is initiated via a folder's action drop-down
192 // by not including said folders name in the temp_dir path.
193 if ($num_recursions <= 1 && $a_initiated_by_folder_action) {
194 $temp_dir = $a_temp_dir;
195 } else {
196 $temp_dir = $a_temp_dir . '/' . ilFileUtils::getASCIIFilename($a_folder_name);
197 }
198
199 $subtree = $tree->getChildsByTypeFilter($a_ref_id, array("fold", "file"));
200
201 foreach ($subtree as $child) {
202 if (!$ilAccess->checkAccess("read", "", $child["ref_id"])) {
203 continue;
204 }
205 if (ilObject::_isInTrash($child["ref_id"])) {
206 continue;
207 }
208 if ($child["type"] == "fold") {
209 $files_from_folder = self::recurseFolder($child["ref_id"], $child['title'], $temp_dir, $num_recursions, $a_initiated_by_folder_action);
210 $files = array_merge($files, $files_from_folder);
211 } else {
212 if (($child["type"] == "file") && (($dirs = self::getFileDirs($child["ref_id"], $child['title'], $temp_dir)) !== false)) {
213 $files[] = $dirs;
214 }
215 }
216 }
217 // ensure that empty folders are also contained in the downloaded zip
218 if (empty($subtree)) {
219 $files[] = [
220 "source_dir" => "",
221 "target_dir" => $temp_dir . '/',
222 ];
223 }
224
225 return $files;
226 }
227
228
233 {
234 return 30;
235 }
236}
$filename
Definition: buildRTE.php:78
Description of class class.
getExpectedTimeOfTaskInSeconds()
int the amount of seconds this task usually taskes. If your task-duration scales with the the amount ...
static getFileDirs($a_ref_id, $a_file_name, $a_temp_dir)
static recurseFolder($a_ref_id, $a_folder_name, $a_temp_dir, $a_num_recursions, $a_initiated_by_folder_action)
run(array $input, \ILIAS\BackgroundTasks\Observer $observer)
@inheritDoc
static getASCIIFilename(string $a_filename)
Component logger with individual log levels by component id.
Class ilObjFile.
static getInstanceByRefId(int $ref_id, bool $stop_on_error=true)
get an instance of an Ilias object by reference id
static _isInTrash(int $ref_id)
global $DIC
Definition: feed.php:28
Class ChatMainBarProvider \MainMenu\Provider.