ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilExport.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
13 class ilExport
14 {
18  protected $log;
19 
20  public static $new_file_structure = array('cat','exc','crs','sess','file','grp','frm', 'usr', 'catr', 'crsr', 'grpr');
21 
22  // this should be part of module.xml and be parsed in the future
23  public static $export_implementer = array("tst", "lm", "glo", "sahs");
24 
25  protected $configs = array();
26 
31  public function __construct()
32  {
33  $this->log = ilLoggerFactory::getLogger('exp');
34  }
35 
43  public function getConfig($a_comp)
44  {
45  // if created, return existing config object
46  if (isset($this->configs[$a_comp])) {
47  return $this->configs[$a_comp];
48  }
49 
50  // create instance of export config object
51  $comp_arr = explode("/", $a_comp);
52  $a_class = "il" . $comp_arr[1] . "ExportConfig";
53  $export_config_file = "./" . $a_comp . "/classes/class." . $a_class . ".php";
54  if (!is_file($export_config_file)) {
55  include_once("./Services/Export/exceptions/class.ilExportException.php");
56  throw new ilExportException('Component "' . $a_comp . '" does not provide ExportConfig class.');
57  }
58  include_once($export_config_file);
59  $exp_config = new $a_class();
60  $this->configs[$a_comp] = $exp_config;
61 
62  return $exp_config;
63  }
64 
65 
70  public static function _getValidExportSubItems($a_ref_id)
71  {
72  global $DIC;
73 
74  $tree = $DIC['tree'];
75 
76  $valid_items = array();
77  $sub_items = $tree->getSubTree($tree->getNodeData($a_ref_id));
78  foreach ($sub_items as $sub_item) {
79  if (in_array($sub_item["type"], self::$export_implementer)) {
80  $valid_items[] = array("type" => $sub_item["type"],
81  "title" => $sub_item["title"], "ref_id" => $sub_item["child"],
82  "obj_id" => $sub_item["obj_id"],
83  "timestamp" =>
84  ilExport::_getLastExportFileDate($sub_item["obj_id"], "xml", $sub_item["type"]));
85  }
86  }
87  return $valid_items;
88  }
89 
97  public static function _getLastExportFileDate($a_obj_id, $a_type = "", $a_obj_type = "")
98  {
99  $files = ilExport::_getExportFiles($a_obj_id, $a_type, $a_obj_type);
100  if (is_array($files)) {
101  $files = ilUtil::sortArray($files, "timestamp", "desc");
102  return $files[0]["timestamp"];
103  }
104  return false;
105  }
106 
114  public static function _getLastExportFileInformation($a_obj_id, $a_type = "", $a_obj_type = "")
115  {
116  $files = ilExport::_getExportFiles($a_obj_id, $a_type, $a_obj_type);
117  if (is_array($files)) {
118  $files = ilUtil::sortArray($files, "timestamp", "desc");
119  return $files[0];
120  }
121  return false;
122  }
123 
133  public static function _getExportDirectory($a_obj_id, $a_type = "xml", $a_obj_type = "", $a_entity = "")
134  {
135  global $DIC;
136 
137  $logger = $DIC->logger()->exp();
138 
139 
140  $objDefinition = $DIC['objDefinition'];
141 
142  $ent = ($a_entity == "")
143  ? ""
144  : "_" . $a_entity;
145 
146 
147  if ($a_obj_type == "") {
148  $a_obj_type = ilObject::_lookupType($a_obj_id);
149  }
150 
151  if (in_array($a_obj_type, self::$new_file_structure)) {
152  include_once './Services/FileSystem/classes/class.ilFileSystemStorage.php';
153  $dir = ilUtil::getDataDir() . DIRECTORY_SEPARATOR;
154  $dir .= 'il' . $objDefinition->getClassName($a_obj_type) . $ent . DIRECTORY_SEPARATOR;
155  $dir .= ilFileSystemStorage::_createPathFromId($a_obj_id, $a_obj_type) . DIRECTORY_SEPARATOR;
156  $dir .= ($a_type == 'xml' ? 'export' : 'export_' . $a_type);
157  return $dir;
158  }
159 
160  include_once './Services/Export/classes/class.ilImportExportFactory.php';
161  $exporter_class = ilImportExportFactory::getExporterClass($a_obj_type);
162  $export_dir = call_user_func(array($exporter_class,'lookupExportDirectory'), $a_obj_type, $a_obj_id, $a_type, $a_entity);
163 
164  $logger->debug('Export dir is ' . $export_dir);
165  return $export_dir;
166  }
167 
171  public static function _getExportFiles($a_obj_id, $a_export_types = "", $a_obj_type = "")
172  {
173  if ($a_obj_type == "") {
174  $a_obj_type = ilObject::_lookupType($a_obj_id);
175  }
176 
177  if ($a_export_types == "") {
178  $a_export_types = array("xml");
179  }
180  if (!is_array($a_export_types)) {
181  $a_export_types = array($a_export_types);
182  }
183 
184  // initialize array
185  $file = array();
186 
187  $types = $a_export_types;
188 
189  foreach ($types as $type) {
190  $dir = ilExport::_getExportDirectory($a_obj_id, $type, $a_obj_type);
191 
192  // quit if import dir not available
193  if (!@is_dir($dir) or
194  !is_writeable($dir)) {
195  continue;
196  }
197 
198  // open directory
199  $h_dir = dir($dir);
200 
201  // get files and save the in the array
202  while ($entry = $h_dir->read()) {
203  if ($entry != "." and
204  $entry != ".." and
205  substr($entry, -4) == ".zip" and
206  preg_match("/^[0-9]{10}_{2}[0-9]+_{2}(" . $a_obj_type . "_)*[0-9]+\.zip\$/", $entry)) {
207  $ts = substr($entry, 0, strpos($entry, "__"));
208  $file[$entry . $type] = array("type" => $type, "file" => $entry,
209  "size" => filesize($dir . "/" . $entry),
210  "timestamp" => $ts);
211  }
212  }
213 
214  // close import directory
215  $h_dir->close();
216  }
217 
218  // sort files
219  ksort($file);
220  reset($file);
221  return $file;
222  }
223 
224 
231  public static function _createExportDirectory($a_obj_id, $a_export_type = "xml", $a_obj_type = "")
232  {
233  global $DIC;
234 
235  $ilErr = $DIC['ilErr'];
236 
237  if ($a_obj_type == "") {
238  $a_obj_type = ilObject::_lookupType($a_obj_id);
239  }
240 
241  $edir = ilExport::_getExportDirectory($a_obj_id, $a_export_type, $a_obj_type);
242  ilUtil::makeDirParents($edir);
243  return true;
244  }
245 
250  public static function _generateIndexFile($a_filename, $a_obj_id, $a_files, $a_type = "")
251  {
252  global $DIC;
253 
254  $lng = $DIC['lng'];
255 
256  $lng->loadLanguageModule("export");
257 
258  if ($a_type == "") {
259  $a_type = ilObject::_lookupType($a_obj_id);
260  }
261  $a_tpl = new ilTemplate("tpl.main.html", true, true);
262  $location_stylesheet = ilUtil::getStyleSheetLocation();
263  $a_tpl->setVariable("LOCATION_STYLESHEET", $location_stylesheet);
264  $a_tpl->getStandardTemplate();
265  $a_tpl->setTitle(ilObject::_lookupTitle($a_obj_id));
266  $a_tpl->setDescription($lng->txt("export_export_date") . ": " .
267  date('Y-m-d H:i:s', time()) . " (" . date_default_timezone_get() . ")");
268  $f_tpl = new ilTemplate("tpl.export_list.html", true, true, "Services/Export");
269  foreach ($a_files as $file) {
270  $f_tpl->setCurrentBlock("file_row");
271  $f_tpl->setVariable("TITLE", $file["title"]);
272  $f_tpl->setVariable("TYPE", $lng->txt("obj_" . $file["type"]));
273  $f_tpl->setVariable("FILE", $file["file"]);
274  $f_tpl->parseCurrentBlock();
275  }
276  $a_tpl->setContent($f_tpl->get());
277  $index_content = $a_tpl->get("DEFAULT", false, false, false, true, false, false);
278 
279  $f = fopen($a_filename, "w");
280  fwrite($f, $index_content);
281  fclose($f);
282  }
283 
287 
288  /***
289  *
290  * - Walk through sequence
291  * - Each step in sequence creates one xml file,
292  * e.g. Services/Mediapool/set_1.xml
293  * - manifest.xml lists all files
294  *
295  * <manifest>
296  * <xmlfile path="Services/Mediapool/set_1.xml"/>
297  * ...
298  * </manifest
299  *
300  *
301  */
302 
312  public function exportObject($a_type, $a_id, $a_target_release = "")
313  {
314  $this->log->debug("export type: $a_type, id: $a_id, target_release: " . $a_target_release);
315 
316  // if no target release specified, use latest major release number
317  if ($a_target_release == "") {
318  $v = explode(".", ILIAS_VERSION_NUMERIC);
319  $a_target_release = $v[0] . "." . $v[1] . ".0";
320  $this->log->debug("target_release set to: " . $a_target_release);
321  }
322 
323  // manifest writer
324  include_once "./Services/Xml/classes/class.ilXmlWriter.php";
325  $this->manifest_writer = new ilXmlWriter();
326  $this->manifest_writer->xmlHeader();
327  $this->manifest_writer->xmlStartTag(
328  'Manifest',
329  array(
330  "MainEntity" => $a_type,
331  "Title" => ilObject::_lookupTitle($a_id),
332  "TargetRelease" => $a_target_release,
333  "InstallationId" => IL_INST_ID,
334  "InstallationUrl" => ILIAS_HTTP_PATH)
335  );
336 
337  // get export class
339  $export_dir = ilExport::_getExportDirectory($a_id, "xml", $a_type);
340  $ts = time();
341 
342  // Workaround for test assessment
343  $sub_dir = $ts . '__' . IL_INST_ID . '__' . $a_type . '_' . $a_id;
344  $new_file = $sub_dir . '.zip';
345 
346  $this->export_run_dir = $export_dir . "/" . $sub_dir;
347  ilUtil::makeDirParents($this->export_run_dir);
348  $this->log->debug("export dir: " . $this->export_run_dir);
349 
350  $this->cnt = array();
351 
352  include_once './Services/Export/classes/class.ilImportExportFactory.php';
353  $class = ilImportExportFactory::getExporterClass($a_type);
354  $comp = ilImportExportFactory::getComponentForExport($a_type);
355 
356  $success = $this->processExporter($comp, $class, $a_type, $a_target_release, $a_id);
357 
358  $this->manifest_writer->xmlEndTag('Manifest');
359 
360  $this->manifest_writer->xmlDumpFile($this->export_run_dir . "/manifest.xml", false);
361 
362  // zip the file
363  $this->log->debug("zip: " . $export_dir . "/" . $new_file);
364  ilUtil::zip($this->export_run_dir, $export_dir . "/" . $new_file);
365  ilUtil::delDir($this->export_run_dir);
366 
367  // Store info about export
368  if ($success) {
369  include_once './Services/Export/classes/class.ilExportFileInfo.php';
370  $exp = new ilExportFileInfo($a_id);
371  $exp->setVersion($a_target_release);
372  $exp->setCreationDate(new ilDateTime($ts, IL_CAL_UNIX));
373  $exp->setExportType('xml');
374  $exp->setFilename($new_file);
375  $exp->create();
376  }
377 
378  return array(
379  "success" => $success,
380  "file" => $new_file,
381  "directory" => $export_dir
382  );
383  }
384 
395  public function exportEntity(
396  $a_entity,
397  $a_id,
398  $a_target_release,
399  $a_component,
400  $a_title,
401  $a_export_dir,
402  $a_type_for_file = ""
403  ) {
404  global $DIC;
405 
406  $objDefinition = $DIC['objDefinition'];
407  $tpl = $DIC['tpl'];
408 
409  // if no target release specified, use latest major release number
410  if ($a_target_release == "") {
411  $v = explode(".", ILIAS_VERSION_NUMERIC);
412  $a_target_release = $v[0] . "." . $v[1] . ".0";
413  }
414 
415  if ($a_type_for_file == "") {
416  $a_type_for_file = $a_entity;
417  }
418 
419  $comp = $a_component;
420  $c = explode("/", $comp);
421  $class = "il" . $c[1] . "Exporter";
422 
423  // manifest writer
424  include_once "./Services/Xml/classes/class.ilXmlWriter.php";
425  $this->manifest_writer = new ilXmlWriter();
426  $this->manifest_writer->xmlHeader();
427  $this->manifest_writer->xmlStartTag(
428  'Manifest',
429  array(
430  "MainEntity" => $a_entity,
431  "Title" => $a_title,
432  "TargetRelease" => $a_target_release,
433  "InstallationId" => IL_INST_ID,
434  "InstallationUrl" => ILIAS_HTTP_PATH)
435  );
436 
437  $export_dir = $a_export_dir;
438  $ts = time();
439 
440  // determine file name and subdirectory
441  $sub_dir = $ts . '__' . IL_INST_ID . '__' . $a_type_for_file . '_' . $a_id;
442  $new_file = $sub_dir . '.zip';
443 
444  $this->export_run_dir = $export_dir . "/" . $sub_dir;
445  ilUtil::makeDirParents($this->export_run_dir);
446 
447  $this->cnt = array();
448 
449  $success = $this->processExporter($comp, $class, $a_entity, $a_target_release, $a_id);
450 
451  $this->manifest_writer->xmlEndTag('Manifest');
452 
453  $this->manifest_writer->xmlDumpFile($this->export_run_dir . "/manifest.xml", false);
454 
455  // zip the file
456  ilUtil::zip($this->export_run_dir, $export_dir . "/" . $new_file);
457  ilUtil::delDir($this->export_run_dir);
458 
459  return array(
460  "success" => $success,
461  "file" => $new_file,
462  "directory" => $export_dir
463  );
464  }
465 
477  public function processExporter($a_comp, $a_class, $a_entity, $a_target_release, $a_id)
478  {
479  $success = true;
480 
481  $this->log->debug("process exporter, comp: " . $a_comp . ", class: " . $a_class . ", entity: " . $a_entity .
482  ", target release " . $a_target_release . ", id: " . $a_id);
483 
484  if (!is_array($a_id)) {
485  if ($a_id == "") {
486  return;
487  }
488  $a_id = array($a_id);
489  }
490 
491  // get exporter object
492  if (!class_exists($a_class)) {
493  $export_class_file = "./" . $a_comp . "/classes/class." . $a_class . ".php";
494  if (!is_file($export_class_file)) {
495  include_once("./Services/Export/exceptions/class.ilExportException.php");
496  throw new ilExportException('Export class file "' . $export_class_file . '" not found.');
497  }
498  include_once($export_class_file);
499  }
500 
501  $exp = new $a_class();
502  $exp->setExport($this);
503  if (!isset($this->cnt[$a_comp])) {
504  $this->cnt[$a_comp] = 1;
505  } else {
506  $this->cnt[$a_comp]++;
507  }
508  $set_dir_relative = $a_comp . "/set_" . $this->cnt[$a_comp];
509  $set_dir_absolute = $this->export_run_dir . "/" . $set_dir_relative;
510  ilUtil::makeDirParents($set_dir_absolute);
511  $this->log->debug("dir: " . $set_dir_absolute);
512 
513  $this->log->debug("init exporter");
514  $exp->init();
515 
516  // process head dependencies
517  $this->log->debug("process head dependencies for " . $a_entity);
518  $sequence = $exp->getXmlExportHeadDependencies($a_entity, $a_target_release, $a_id);
519  foreach ($sequence as $s) {
520  $comp = explode("/", $s["component"]);
521  $exp_class = "il" . $comp[1] . "Exporter";
522  $s = $this->processExporter(
523  $s["component"],
524  $exp_class,
525  $s["entity"],
526  $a_target_release,
527  $s["ids"]
528  );
529  if (!$s) {
530  $success = false;
531  }
532  }
533 
534  // write export.xml file
535  $export_writer = new ilXmlWriter();
536  $export_writer->xmlHeader();
537 
538  $sv = $exp->determineSchemaVersion($a_entity, $a_target_release);
539  $this->log->debug("schema version for entity: $a_entity, target release: $a_target_release");
540  $this->log->debug("...is: " . $sv["schema_version"] . ", namespace: " . $sv["namespace"] .
541  ", xsd file: " . $sv["xsd_file"] . ", uses_dataset: " . ((int) $sv["uses_dataset"]));
542 
543  $attribs = array("InstallationId" => IL_INST_ID,
544  "InstallationUrl" => ILIAS_HTTP_PATH,
545  "Entity" => $a_entity, "SchemaVersion" => $sv["schema_version"], "TargetRelease" => $a_target_release,
546  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
547  "xmlns:exp" => "http://www.ilias.de/Services/Export/exp/4_1",
548  "xsi:schemaLocation" => "http://www.ilias.de/Services/Export/exp/4_1 " . ILIAS_HTTP_PATH . "/xml/ilias_export_4_1.xsd"
549  );
550  if ($sv["namespace"] != "" && $sv["xsd_file"] != "") {
551  $attribs["xsi:schemaLocation"] .= " " . $sv["namespace"] . " " .
552  ILIAS_HTTP_PATH . "/xml/" . $sv["xsd_file"];
553  $attribs["xmlns"] = $sv["namespace"];
554  }
555  if ($sv["uses_dataset"]) {
556  $attribs["xsi:schemaLocation"] .= " " .
557  "http://www.ilias.de/Services/DataSet/ds/4_3 " . ILIAS_HTTP_PATH . "/xml/ilias_ds_4_3.xsd";
558  $attribs["xmlns:ds"] = "http://www.ilias.de/Services/DataSet/ds/4_3";
559  }
560 
561 
562  $export_writer->xmlStartTag('exp:Export', $attribs);
563 
564  $dir_cnt = 1;
565  foreach ($a_id as $id) {
566  $exp->setExportDirectories(
567  $set_dir_relative . "/expDir_" . $dir_cnt,
568  $set_dir_absolute . "/expDir_" . $dir_cnt
569  );
570  $export_writer->xmlStartTag('exp:ExportItem', array("Id" => $id));
571  //$xml = $exp->getXmlRepresentation($a_entity, $a_target_release, $id);
572  $xml = $exp->getXmlRepresentation($a_entity, $sv["schema_version"], $id);
573  $export_writer->appendXml($xml);
574  $export_writer->xmlEndTag('exp:ExportItem');
575  $dir_cnt++;
576  }
577 
578  $export_writer->xmlEndTag('exp:Export');
579  $export_writer->xmlDumpFile($set_dir_absolute . "/export.xml", false);
580 
581  $this->manifest_writer->xmlElement(
582  "ExportFile",
583  array("Component" => $a_comp, "Path" => $set_dir_relative . "/export.xml")
584  );
585 
586  // process tail dependencies
587  $this->log->debug("process tail dependencies of " . $a_entity);
588  $sequence = $exp->getXmlExportTailDependencies($a_entity, $a_target_release, $a_id);
589  foreach ($sequence as $s) {
590  $comp = explode("/", $s["component"]);
591  $exp_class = "il" . $comp[1] . "Exporter";
592  $s = $this->processExporter(
593  $s["component"],
594  $exp_class,
595  $s["entity"],
596  $a_target_release,
597  $s["ids"]
598  );
599  if (!$s) {
600  $success = false;
601  }
602  }
603 
604  $this->log->debug("returning " . ((int) $success) . " for " . $a_entity);
605  return $success;
606  }
607 }
static _createExportDirectory($a_obj_id, $a_export_type="xml", $a_obj_type="")
static sortArray( $array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static makeDirParents($a_dir)
Create a new directory and all parent directories.
exportObject($a_type, $a_id, $a_target_release="")
Export an ILIAS object (the object type must be known by objDefinition)
static $new_file_structure
$files
Definition: metarefresh.php:49
const ILIAS_VERSION_NUMERIC
$type
global $DIC
Definition: saml.php:7
static getStyleSheetLocation($mode="output", $a_css_name="", $a_css_location="")
get full style sheet file name (path inclusive) of current user
$tpl
Definition: ilias.php:10
static _getExportFiles($a_obj_id, $a_export_types="", $a_obj_type="")
Get Export Files for a repository object.
getConfig($a_comp)
Get configuration (note that configurations are optional, null may be returned!)
if(!array_key_exists('StateId', $_REQUEST)) $id
XML writer class.
static _lookupTitle($a_id)
lookup object title
$s
Definition: pwgen.php:45
General export exception.
exportEntity( $a_entity, $a_id, $a_target_release, $a_component, $a_title, $a_export_dir, $a_type_for_file="")
Export an ILIAS entity.
const IL_CAL_UNIX
$ilErr
Definition: raiseError.php:18
static _createPathFromId($a_container_id, $a_name)
Create a path from an id: e.g 12345 will be converted to 12/34/<name>_5.
$a_type
Definition: workflow.php:92
$success
Definition: Utf8Test.php:86
$lng
static _getLastExportFileDate($a_obj_id, $a_type="", $a_obj_type="")
Get date of last export file.
processExporter($a_comp, $a_class, $a_entity, $a_target_release, $a_id)
Process exporter.
static _getValidExportSubItems($a_ref_id)
Get a list of subitems of a repository resource, that implement the export.
special template class to simplify handling of ITX/PEAR
Stores information of creation date and versions of export files
__construct()
Default constructor.
Date and time handling
static zip($a_dir, $a_file, $compress_content=false)
zips given directory/file into given zip.file
static _lookupType($a_id, $a_reference=false)
lookup object type
static getDataDir()
get data directory (outside webspace)
static _getExportDirectory($a_obj_id, $a_type="xml", $a_obj_type="", $a_entity="")
Get export directory for an repository object.
static _generateIndexFile($a_filename, $a_obj_id, $a_files, $a_type="")
Generates an index.html file including links to all xml files included (for container exports) ...
static getLogger($a_component_id)
Get component logger.
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static $export_implementer
static _getLastExportFileInformation($a_obj_id, $a_type="", $a_obj_type="")
Get last export file information.