ILIAS  release_7 Revision v7.30-3-g800a261c036
All Data Structures Namespaces Files Functions Variables Modules Pages
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 }
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)
Description of class class.
Class ChatMainBarProvider .
static _isInTrash($a_ref_id)
checks wether object is in trash
static getASCIIFilename($a_filename)
convert utf8 to ascii filename
run(array $input, \ILIAS\BackgroundTasks\Observer $observer)
global $DIC
Definition: goto.php:24
if(!defined('PATH_SEPARATOR')) $GLOBALS['_PEAR_default_error_mode']
Definition: PEAR.php:64
$filename
Definition: buildRTE.php:89
static getInstanceByRefId($a_ref_id, $stop_on_error=true)
get an instance of an Ilias object by reference id
getExpectedTimeOfTaskInSeconds()
int the amount of seconds this task usually taskes. If your task-duration scales with the the amount ...