ILIAS  release_7 Revision v7.30-3-g800a261c036
class.ilCollectFilesJob.php
Go to the documentation of this file.
1<?php
2/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
3
7
15{
21 private static $targets = [];
22
23 private $logger = null;
24
28 public function __construct()
29 {
30 $this->logger = $GLOBALS['DIC']->logger()->cal();
31 }
32
33
37 public function getInputTypes()
38 {
39 return
40 [
41 new SingleType(ilCopyDefinition::class),
42 new SingleType(BooleanValue::class),
43 ];
44 }
45
46
50 public function getOutputType()
51 {
52 return new SingleType(ilCopyDefinition::class);
53 }
54
55
59 public function isStateless()
60 {
61 return true;
62 }
63
64
69 public function run(array $input, \ILIAS\BackgroundTasks\Observer $observer)
70 {
71 $this->logger->debug('Start collecting files!');
72 $this->logger->dump($input);
73 $definition = $input[0];
74 $initiated_by_folder_action = $input[1]->getValue();
75 $object_ref_ids = $definition->getObjectRefIds();
76 $files = array();
77
78 foreach ($object_ref_ids as $object_ref_id) {
79 $object = ilObjectFactory::getInstanceByRefId($object_ref_id);
80 $object_type = $object->getType();
81 $object_name = $object->getTitle();
82 $object_temp_dir = ""; // empty as content will be added in recurseFolder and getFileDirs
83
84 if ($object_type == "fold") {
85 $num_recursions = 0;
86 $files_from_folder = self::recurseFolder($object_ref_id, $object_name, $object_temp_dir, $num_recursions, $initiated_by_folder_action);
87 $files = array_merge($files, $files_from_folder);
88 } else {
89 if (($object_type == "file") and (($file_dirs = self::getFileDirs($object_ref_id, $object_name, $object_temp_dir)) != false)) {
90 $files[] = $file_dirs;
91 }
92 }
93 }
94 $this->logger->debug('Collected files:');
95 $this->logger->dump($files);
96
97 $num_files = 0;
98 foreach ($files as $file) {
99 $definition->addCopyDefinition($file['source_dir'], $file['target_dir']);
100 $this->logger->debug('Added new copy definition: ' . $file['source_dir'] . ' -> ' . $file['target_dir']);
101
102 // count files only (without empty directories)
103 $is_empty_folder = preg_match_all("/\/$/", $file['target_dir']);
104 if (!$is_empty_folder) {
105 $num_files++;
106 }
107 }
108 $definition->setObjectRefIds($object_ref_ids);
109 $definition->setNumFiles($num_files);
110
111 return $definition;
112 }
113
119 private static function getFileDirs($a_ref_id, $a_file_name, $a_temp_dir)
120 {
121 global $DIC;
122
123 $user = $DIC->user();
124 $ilAccess = $DIC->access();
125 if ($ilAccess->checkAccessOfUser($user->getId(), "read", "", $a_ref_id)) {
126 $file = new ilObjFile($a_ref_id);
127 $source_dir = $file->getFile();
128 if (@!is_file($source_dir)) {
129 return false;
130 }
131 $target_dir = $a_temp_dir . '/' . ilUtil::getASCIIFilename($a_file_name);
132
133 // #25025: allow duplicate filenames by appending an incrementing
134 // number per duplicate in brackets to the name.
135 // Example: test.txt, test (1).txt, test (2).txt, ...
136 if (isset(self::$targets[$target_dir])) {
137 $target_info = pathinfo($target_dir);
138 $filename = $target_info["filename"];
139 $extension = isset($target_info["extension"]) ? "." . $target_info["extension"] : "";
140 $target_dir = $a_temp_dir . $filename . " (" . ++self::$targets[$target_dir] . ")" . $extension;
141 } else {
142 self::$targets[$target_dir] = 0;
143 }
144
145 return [
146 "source_dir" => $source_dir,
147 "target_dir" => $target_dir,
148 ];
149 }
150
151 return false;
152 }
153
154
162 private static function recurseFolder($a_ref_id, $a_folder_name, $a_temp_dir, $a_num_recursions, $a_initiated_by_folder_action)
163 {
164 global $DIC;
165
166 $num_recursions = $a_num_recursions + 1;
167 $tree = $DIC->repositoryTree();
168 $ilAccess = $DIC->access();
169 $files = array();
170
171 // Avoid the duplication of the uppermost folder when the download is initiated via a folder's action drop-down
172 // by not including said folders name in the temp_dir path.
173 if (($num_recursions <= 1) and ($a_initiated_by_folder_action)) {
174 $temp_dir = $a_temp_dir;
175 } else {
176 $temp_dir = $a_temp_dir . '/' . ilUtil::getASCIIFilename($a_folder_name);
177 }
178
179 $subtree = $tree->getChildsByTypeFilter($a_ref_id, array("fold", "file"));
180
181 foreach ($subtree as $child) {
182 if (!$ilAccess->checkAccess("read", "", $child["ref_id"])) {
183 continue;
184 }
185 if (ilObject::_isInTrash($child["ref_id"])) {
186 continue;
187 }
188 if ($child["type"] == "fold") {
189 $files_from_folder = self::recurseFolder($child["ref_id"], $child['title'], $temp_dir, $num_recursions, $a_initiated_by_folder_action);
190 $files = array_merge($files, $files_from_folder);
191 } else {
192 if (($child["type"] == "file") and (($dirs = self::getFileDirs($child["ref_id"], $child['title'], $temp_dir)) != false)) {
193 $files[] = $dirs;
194 }
195 }
196 }
197 // ensure that empty folders are also contained in the downloaded zip
198 if (empty($subtree)) {
199 $files[] = [
200 "source_dir" => "",
201 "target_dir" => $temp_dir . '/',
202 ];
203 }
204
205 return $files;
206 }
207
208
213 {
214 return 30;
215 }
216}
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$filename
Definition: buildRTE.php:89
An exception for terminatinating execution or to throw for unit testing.
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)
Please note that this method must only be called ONCE in order to detect duplicate entries.
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
Class ilObjFile.
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
static _isInTrash($a_ref_id)
checks wether object is in trash
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
global $DIC
Definition: goto.php:24
Class ChatMainBarProvider \MainMenu\Provider.