ILIAS  trunk Revision v11.0_alpha-2638-g80c1d007f79
ilExportFilesToIRSSMigration.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
24 
26 {
27  protected ilDBInterface $db;
28 
29  public function getLabel(): string
30  {
31  return "ilExportFilesToIRSSMigration";
32  }
33 
35  {
36  return 5;
37  }
38 
39  public function getPreconditions(Environment $environment): array
40  {
41  return array_merge(
43  [
47  ]
48  );
49  }
50 
51  public function prepare(Environment $environment): void
52  {
53  $this->db = $environment->getResource(Environment::RESOURCE_DATABASE);
54  }
55 
56  public function step(Environment $environment): void
57  {
58  $res_export_file_info = $this->db->query(
59  "SELECT obj_id, export_type, filename, create_date FROM export_file_info WHERE migrated = 0 LIMIT 1"
60  );
61  $row_export_file_info = $res_export_file_info->fetchAssoc();
62  if (is_null($row_export_file_info)) {
63  return;
64  }
65  $obj_id = (int) $row_export_file_info['obj_id'];
66  $export_type = $row_export_file_info['export_type'];
67  $filename = $row_export_file_info['filename'];
68  $res_object_data = $this->db->query(
69  "SELECT type FROM object_data WHERE obj_id = " . $this->db->quote((int) $row_export_file_info['obj_id'], ilDBConstants::T_INTEGER)
70  );
71  $row_object_data = $res_object_data->fetchAssoc();
72  # Export does not exist anymore, mark as migrated
73  if (is_null($row_object_data)) {
74  $this->updateMigrated($obj_id, $export_type, $filename);
75  return;
76  }
77  $res_il_object_def = $this->db->query(
78  "SELECT class_name, component, location, id FROM il_object_def where id = " . $this->db->quote($row_object_data['type'], ilDBConstants::T_TEXT)
79  );
80  $row_il_object_def = $this->db->fetchAssoc($res_il_object_def);
81  # Object type is not defined or plugin and cannot be migrated, mark as such
82  if (is_null($row_il_object_def)) {
83  $this->updateMigratedUnsupportedObjectType($obj_id, $export_type, $filename);
84  return;
85  }
86  $res_il_plugin = $this->db->query("SELECT plugin_id FROM il_plugin");
87  $plugin_ids = [];
88  while ($row_il_plugin = $res_il_plugin->fetchAssoc()) {
89  $plugin_ids[] = $row_il_plugin['plugin_id'];
90  }
91  $classname = $row_il_object_def['class_name'];
92  $create_date = $row_export_file_info['create_date'];
93  $type = $row_object_data['type'];
94  $component_for_type = $row_il_object_def['component'];
95  $is_plugin = in_array($row_il_object_def["id"], $plugin_ids);
96  $location = $row_il_object_def['location'];
97  $export_dir = $this->getExportDirectory(
98  $classname,
99  $is_plugin,
100  $location,
101  $component_for_type,
102  $obj_id,
103  $export_type,
104  $type
105  );
106  $file_path = $export_dir . DIRECTORY_SEPARATOR . $filename;
107  # Export file was deleted, mark as migrated
108  if (!file_exists($file_path)) {
109  $this->updateMigrated($obj_id, $export_type, $filename);
110  return;
111  }
112  $irss_helper = new ilResourceStorageMigrationHelper(new ResourceStakeholder(), $environment);
113  $rid = $irss_helper->movePathToStorage($file_path, 6, null, null, false);
114  if (is_null($rid)) {
115  throw new \Exception('Could not store:' . $file_path);
116  }
117  $this->db->manipulate(
118  "INSERT INTO export_files (object_id, rid, owner_id, timestamp) VALUES ("
119  . $this->db->quote($obj_id, ilDBConstants::T_INTEGER) . ", "
120  . $this->db->quote($rid->serialize(), ilDBConstants::T_TEXT) . ", "
121  . $this->db->quote(6, ilDBConstants::T_INTEGER) . ", "
122  . $this->db->quote($create_date, ilDBConstants::T_DATE) . ")"
123  );
124  # Export file was moved to irss, mark as migrated
125  $this->updateMigrated($obj_id, $export_type, $filename);
126  }
127 
128  public function getRemainingAmountOfSteps(): int
129  {
130  $query = "SELECT COUNT(*) as count FROM export_file_info where migrated = 0";
131  $res = $this->db->query($query);
132  $row = $res->fetchAssoc();
133  if (is_null($row)) {
134  return 0;
135  }
136  return (int) $row['count'];
137  }
138 
139  protected function updateMigrated(
140  int $obj_id,
141  string $export_type,
142  string $filename
143  ): void {
144  $this->db->manipulate(
145  "UPDATE export_file_info SET migrated = 1 WHERE"
146  . " obj_id = " . $this->db->quote($obj_id, ilDBConstants::T_INTEGER)
147  . " AND export_type = " . $this->db->quote($export_type, ilDBConstants::T_TEXT)
148  . " AND filename = " . $this->db->quote($filename, ilDBConstants::T_TEXT)
149  );
150  }
151 
153  int $obj_id,
154  string $export_type,
155  string $filename
156  ): void {
157  $this->db->manipulate(
158  "UPDATE export_file_info SET migrated = 2 WHERE"
159  . " obj_id = " . $this->db->quote($obj_id, ilDBConstants::T_INTEGER)
160  . " AND export_type = " . $this->db->quote($export_type, ilDBConstants::T_TEXT)
161  . " AND filename = " . $this->db->quote($filename, ilDBConstants::T_TEXT)
162  );
163  }
164 
165  protected function getExportDirectory(
166  string $class_name,
167  bool $is_plugin,
168  string $location,
169  string $component_for_type,
170  int $a_obj_id,
171  string $a_type = "xml",
172  string $a_obj_type = "",
173  string $a_entity = ""
174  ): string {
175  $ent = ($a_entity == "")
176  ? ""
177  : "_" . $a_entity;
178  if ($a_obj_type == "") {
179  $a_obj_type = ilObject::_lookupType($a_obj_id);
180  }
181  $new_file_structure = [
182  'cat', 'exc', 'crs', 'sess',
183  'file', 'grp', 'frm', 'usr',
184  'catr', 'crsr', 'grpr'
185  ];
186  if (in_array($a_obj_type, $new_file_structure)) {
187  $dir = ilFileUtils::getDataDir() . DIRECTORY_SEPARATOR;
188  $dir .= 'il' . $class_name . $ent . DIRECTORY_SEPARATOR;
189  $dir .= $this->createPathFromId($a_obj_id, $a_obj_type) . DIRECTORY_SEPARATOR;
190  $dir .= ($a_type == 'xml' ? 'export' : 'export_' . $a_type);
191  return $dir;
192  }
193  $exporter_class = $this->getExporterClass(
194  $a_obj_type,
195  $is_plugin,
196  $class_name,
197  $location,
198  $component_for_type
199  );
200  $export_dir = call_user_func(
201  array($exporter_class, 'lookupExportDirectory'),
202  $a_obj_type,
203  $a_obj_id,
204  $a_type,
205  $a_entity
206  );
207  return $export_dir;
208  }
209 
210  protected function createPathFromId(int $a_container_id, string $a_name): string
211  {
212  $max_exponent = 3;
213  $factor = 100;
214  $path = [];
215  $found = false;
216  $num = $a_container_id;
217  $path_string = '';
218  for ($i = $max_exponent; $i > 0; $i--) {
219  $factor = pow($factor, $i);
220  if (($tmp = (int) ($num / $factor)) or $found) {
221  $path[] = $tmp;
222  $num = $num % $factor;
223  $found = true;
224  }
225  }
226  if (count($path)) {
227  $path_string = (implode('/', $path) . '/');
228  }
229  return $path_string . $a_name . '_' . $a_container_id;
230  }
231 
232  protected function getExporterClass(
233  string $a_type,
234  bool $is_plugin,
235  string $class_name,
236  string $location,
237  string $component_for_type
238  ): string {
239  if ($is_plugin) {
240  $classname = 'il' . $class_name . 'Exporter';
241  if (include_once $location . '/class.' . $classname . '.php') {
242  return $classname;
243  }
244  } else {
245  $comp = $component_for_type;
246  $componentParts = explode("/", $comp);
247  $class = array_pop($componentParts);
248  $class = "il" . $class . "Exporter";
249  // page component plugin exporter classes are already included
250  // the component is not registered by ilObjDefinition
251  if (class_exists($class)) {
252  return $class;
253  }
254  // the next line had a "@" in front of the include_once
255  // I removed this because it tages ages to track down errors
256  // if the include class contains parse errors.
257  // Alex, 20 Jul 2012
258  if (include_once "./" . $comp . "/classes/class." . $class . ".php") {
259  return $class;
260  }
261  }
262  throw new InvalidArgumentException('Invalid exporter type given');
263  }
264 }
getPreconditions(Environment $environment)
Objectives the migration depend on.
$res
Definition: ltiservices.php:66
getExportDirectory(string $class_name, bool $is_plugin, string $location, string $component_for_type, int $a_obj_id, string $a_type="xml", string $a_obj_type="", string $a_entity="")
$location
Definition: buildRTE.php:22
A migration is a potentially long lasting operation that can be broken into discrete steps...
Definition: Migration.php:28
getRemainingAmountOfSteps()
Count up how many "things" need to be migrated.
step(Environment $environment)
Run one step of the migration.
updateMigrated(int $obj_id, string $export_type, string $filename)
$path
Definition: ltiservices.php:29
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null
prepare(Environment $environment)
Prepare the migration by means of some environment.
createPathFromId(int $a_container_id, string $a_name)
getResource(string $id)
Consumers of this method should check if the result is what they expect, e.g.
static getDataDir()
get data directory (outside webspace)
$filename
Definition: buildRTE.php:78
getExporterClass(string $a_type, bool $is_plugin, string $class_name, string $location, string $component_for_type)
An environment holds resources to be used in the setup process.
Definition: Environment.php:27
updateMigratedUnsupportedObjectType(int $obj_id, string $export_type, string $filename)
static _lookupType(int $id, bool $reference=false)
getDefaultAmountOfStepsPerRun()
Tell the default amount of steps to be executed for one run of the migration.