ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 $tree;
73 
74  $valid_items = array();
75  $sub_items = $tree->getSubTree($tree->getNodeData($a_ref_id));
76  foreach ($sub_items as $sub_item) {
77  if (in_array($sub_item["type"], self::$export_implementer)) {
78  $valid_items[] = array("type" => $sub_item["type"],
79  "title" => $sub_item["title"], "ref_id" => $sub_item["child"],
80  "obj_id" => $sub_item["obj_id"],
81  "timestamp" =>
82  ilExport::_getLastExportFileDate($sub_item["obj_id"], "xml", $sub_item["type"]));
83  }
84  }
85  return $valid_items;
86  }
87 
95  public static function _getLastExportFileDate($a_obj_id, $a_type = "", $a_obj_type = "")
96  {
97  $files = ilExport::_getExportFiles($a_obj_id, $a_type, $a_obj_type);
98  if (is_array($files)) {
99  $files = ilUtil::sortArray($files, "timestamp", "desc");
100  return $files[0]["timestamp"];
101  }
102  return false;
103  }
104 
112  public static function _getLastExportFileInformation($a_obj_id, $a_type = "", $a_obj_type = "")
113  {
114  $files = ilExport::_getExportFiles($a_obj_id, $a_type, $a_obj_type);
115  if (is_array($files)) {
116  $files = ilUtil::sortArray($files, "timestamp", "desc");
117  return $files[0];
118  }
119  return false;
120  }
121 
131  public static function _getExportDirectory($a_obj_id, $a_type = "xml", $a_obj_type = "", $a_entity = "")
132  {
133  global $objDefinition;
134 
135  $ent = ($a_entity == "")
136  ? ""
137  : "_" . $a_entity;
138 
139 
140  if ($a_obj_type == "") {
141  $a_obj_type = ilObject::_lookupType($a_obj_id);
142  }
143 
144  if (in_array($a_obj_type, self::$new_file_structure)) {
145  include_once './Services/FileSystem/classes/class.ilFileSystemStorage.php';
146  $dir = ilUtil::getDataDir() . DIRECTORY_SEPARATOR;
147  $dir .= 'il' . $objDefinition->getClassName($a_obj_type) . $ent . DIRECTORY_SEPARATOR;
148  $dir .= ilFileSystemStorage::_createPathFromId($a_obj_id, $a_obj_type) . DIRECTORY_SEPARATOR;
149  $dir .= ($a_type == 'xml' ? 'export' : 'export_' . $a_type);
150  return $dir;
151  }
152 
153  include_once './Services/Export/classes/class.ilImportExportFactory.php';
154  $exporter_class = ilImportExportFactory::getExporterClass($a_obj_type);
155  $export_dir = call_user_func(array($exporter_class,'lookupExportDirectory'), $a_obj_type, $a_obj_id, $a_type, $a_entity);
156 
157  $GLOBALS['ilLog']->write(__METHOD__ . ': Export dir is ' . $export_dir);
158  return $export_dir;
159  }
160 
164  public static function _getExportFiles($a_obj_id, $a_export_types = "", $a_obj_type = "")
165  {
166  $GLOBALS['ilLog']->write(__METHOD__);
167 
168  if ($a_obj_type == "") {
169  $a_obj_type = ilObject::_lookupType($a_obj_id);
170  }
171 
172  if ($a_export_types == "") {
173  $a_export_types = array("xml");
174  }
175  if (!is_array($a_export_types)) {
176  $a_export_types = array($a_export_types);
177  }
178 
179  // initialize array
180  $file = array();
181 
182  $types = $a_export_types;
183 
184  foreach ($types as $type) {
185  $dir = ilExport::_getExportDirectory($a_obj_id, $type, $a_obj_type);
186 
187  // quit if import dir not available
188  if (!@is_dir($dir) or
189  !is_writeable($dir)) {
190  continue;
191  }
192 
193  // open directory
194  $h_dir = dir($dir);
195 
196  // get files and save the in the array
197  while ($entry = $h_dir->read()) {
198  if ($entry != "." and
199  $entry != ".." and
200  substr($entry, -4) == ".zip" and
201  preg_match("/^[0-9]{10}_{2}[0-9]+_{2}(" . $a_obj_type . "_)*[0-9]+\.zip\$/", $entry)) {
202  $ts = substr($entry, 0, strpos($entry, "__"));
203  $file[$entry . $type] = array("type" => $type, "file" => $entry,
204  "size" => filesize($dir . "/" . $entry),
205  "timestamp" => $ts);
206  }
207  }
208 
209  // close import directory
210  $h_dir->close();
211  }
212 
213  // sort files
214  ksort($file);
215  reset($file);
216  return $file;
217  }
218 
219 
226  public static function _createExportDirectory($a_obj_id, $a_export_type = "xml", $a_obj_type = "")
227  {
228  global $ilErr;
229 
230  if ($a_obj_type == "") {
231  $a_obj_type = ilObject::_lookupType($a_obj_id);
232  }
233 
234  $edir = ilExport::_getExportDirectory($a_obj_id, $a_export_type, $a_obj_type);
235  ilUtil::makeDirParents($edir);
236  return true;
237  }
238 
243  public static function _generateIndexFile($a_filename, $a_obj_id, $a_files, $a_type = "")
244  {
245  global $lng;
246 
247  $lng->loadLanguageModule("export");
248 
249  if ($a_type == "") {
250  $a_type = ilObject::_lookupType($a_obj_id);
251  }
252  $a_tpl = new ilTemplate("tpl.main.html", true, true);
253  $location_stylesheet = ilUtil::getStyleSheetLocation();
254  $a_tpl->setVariable("LOCATION_STYLESHEET", $location_stylesheet);
255  $a_tpl->getStandardTemplate();
256  $a_tpl->setTitle(ilObject::_lookupTitle($a_obj_id));
257  $a_tpl->setDescription($lng->txt("export_export_date") . ": " .
258  date('Y-m-d H:i:s', time()) . " (" . date_default_timezone_get() . ")");
259  $f_tpl = new ilTemplate("tpl.export_list.html", true, true, "Services/Export");
260  foreach ($a_files as $file) {
261  $f_tpl->setCurrentBlock("file_row");
262  $f_tpl->setVariable("TITLE", $file["title"]);
263  $f_tpl->setVariable("TYPE", $lng->txt("obj_" . $file["type"]));
264  $f_tpl->setVariable("FILE", $file["file"]);
265  $f_tpl->parseCurrentBlock();
266  }
267  $a_tpl->setContent($f_tpl->get());
268  $index_content = $a_tpl->get("DEFAULT", false, false, false, true, false, false);
269 
270  $f = fopen($a_filename, "w");
271  fwrite($f, $index_content);
272  fclose($f);
273  }
274 
278 
279  /***
280  *
281  * - Walk through sequence
282  * - Each step in sequence creates one xml file,
283  * e.g. Services/Mediapool/set_1.xml
284  * - manifest.xml lists all files
285  *
286  * <manifest>
287  * <xmlfile path="Services/Mediapool/set_1.xml"/>
288  * ...
289  * </manifest
290  *
291  *
292  */
293 
303  public function exportObject($a_type, $a_id, $a_target_release = "")
304  {
305  $this->log->debug("export type: $a_type, id: $a_id, target_release: " . $a_target_release);
306 
307  // if no target release specified, use latest major release number
308  if ($a_target_release == "") {
309  $v = explode(".", ILIAS_VERSION_NUMERIC);
310  $a_target_release = $v[0] . "." . $v[1] . ".0";
311  $this->log->debug("target_release set to: " . $a_target_release);
312  }
313 
314  // manifest writer
315  include_once "./Services/Xml/classes/class.ilXmlWriter.php";
316  $this->manifest_writer = new ilXmlWriter();
317  $this->manifest_writer->xmlHeader();
318  $this->manifest_writer->xmlStartTag(
319  'Manifest',
320  array(
321  "MainEntity" => $a_type,
322  "Title" => ilObject::_lookupTitle($a_id),
323  "TargetRelease" => $a_target_release,
324  "InstallationId" => IL_INST_ID,
325  "InstallationUrl" => ILIAS_HTTP_PATH)
326  );
327 
328  // get export class
330  $export_dir = ilExport::_getExportDirectory($a_id, "xml", $a_type);
331  $ts = time();
332 
333  // Workaround for test assessment
334  $sub_dir = $ts . '__' . IL_INST_ID . '__' . $a_type . '_' . $a_id;
335  $new_file = $sub_dir . '.zip';
336 
337  $this->export_run_dir = $export_dir . "/" . $sub_dir;
338  ilUtil::makeDirParents($this->export_run_dir);
339  $this->log->debug("export dir: " . $this->export_run_dir);
340 
341  $this->cnt = array();
342 
343  include_once './Services/Export/classes/class.ilImportExportFactory.php';
344  $class = ilImportExportFactory::getExporterClass($a_type);
345  $comp = ilImportExportFactory::getComponentForExport($a_type);
346 
347  $success = $this->processExporter($comp, $class, $a_type, $a_target_release, $a_id);
348 
349  $this->manifest_writer->xmlEndTag('Manifest');
350 
351  $this->manifest_writer->xmlDumpFile($this->export_run_dir . "/manifest.xml", false);
352 
353  // zip the file
354  $this->log->debug("zip: " . $export_dir . "/" . $new_file);
355  ilUtil::zip($this->export_run_dir, $export_dir . "/" . $new_file);
356  ilUtil::delDir($this->export_run_dir);
357 
358  // Store info about export
359  if ($success) {
360  include_once './Services/Export/classes/class.ilExportFileInfo.php';
361  $exp = new ilExportFileInfo($a_id);
362  $exp->setVersion($a_target_release);
363  $exp->setCreationDate(new ilDateTime($ts, IL_CAL_UNIX));
364  $exp->setExportType('xml');
365  $exp->setFilename($new_file);
366  $exp->create();
367  }
368 
369  return array(
370  "success" => $success,
371  "file" => $new_file,
372  "directory" => $export_dir
373  );
374  }
375 
386  public function exportEntity(
387  $a_entity,
388  $a_id,
389  $a_target_release,
390  $a_component,
391  $a_title,
392  $a_export_dir,
393  $a_type_for_file = ""
394  ) {
395  global $objDefinition, $tpl;
396 
397  // if no target release specified, use latest major release number
398  if ($a_target_release == "") {
399  $v = explode(".", ILIAS_VERSION_NUMERIC);
400  $a_target_release = $v[0] . "." . $v[1] . ".0";
401  }
402 
403  if ($a_type_for_file == "") {
404  $a_type_for_file = $a_entity;
405  }
406 
407  $comp = $a_component;
408  $c = explode("/", $comp);
409  $class = "il" . $c[1] . "Exporter";
410 
411  // manifest writer
412  include_once "./Services/Xml/classes/class.ilXmlWriter.php";
413  $this->manifest_writer = new ilXmlWriter();
414  $this->manifest_writer->xmlHeader();
415  $this->manifest_writer->xmlStartTag(
416  'Manifest',
417  array(
418  "MainEntity" => $a_entity,
419  "Title" => $a_title,
420  "TargetRelease" => $a_target_release,
421  "InstallationId" => IL_INST_ID,
422  "InstallationUrl" => ILIAS_HTTP_PATH)
423  );
424 
425  $export_dir = $a_export_dir;
426  $ts = time();
427 
428  // determine file name and subdirectory
429  $sub_dir = $ts . '__' . IL_INST_ID . '__' . $a_type_for_file . '_' . $a_id;
430  $new_file = $sub_dir . '.zip';
431 
432  $this->export_run_dir = $export_dir . "/" . $sub_dir;
433  ilUtil::makeDirParents($this->export_run_dir);
434 
435  $this->cnt = array();
436 
437  $success = $this->processExporter($comp, $class, $a_entity, $a_target_release, $a_id);
438 
439  $this->manifest_writer->xmlEndTag('Manifest');
440 
441  $this->manifest_writer->xmlDumpFile($this->export_run_dir . "/manifest.xml", false);
442 
443  // zip the file
444  ilUtil::zip($this->export_run_dir, $export_dir . "/" . $new_file);
445  ilUtil::delDir($this->export_run_dir);
446 
447  return array(
448  "success" => $success,
449  "file" => $new_file,
450  "directory" => $export_dir
451  );
452  }
453 
465  public function processExporter($a_comp, $a_class, $a_entity, $a_target_release, $a_id)
466  {
467  $success = true;
468 
469  $this->log->debug("process exporter, comp: " . $a_comp . ", class: " . $a_class . ", entity: " . $a_entity .
470  ", target release " . $a_target_release . ", id: " . $a_id);
471 
472  if (!is_array($a_id)) {
473  if ($a_id == "") {
474  return;
475  }
476  $a_id = array($a_id);
477  }
478 
479  // get exporter object
480  if (!class_exists($a_class)) {
481  $export_class_file = "./" . $a_comp . "/classes/class." . $a_class . ".php";
482  if (!is_file($export_class_file)) {
483  include_once("./Services/Export/exceptions/class.ilExportException.php");
484  throw new ilExportException('Export class file "' . $export_class_file . '" not found.');
485  }
486  include_once($export_class_file);
487  }
488 
489  $exp = new $a_class();
490  $exp->setExport($this);
491  if (!isset($this->cnt[$a_comp])) {
492  $this->cnt[$a_comp] = 1;
493  } else {
494  $this->cnt[$a_comp]++;
495  }
496  $set_dir_relative = $a_comp . "/set_" . $this->cnt[$a_comp];
497  $set_dir_absolute = $this->export_run_dir . "/" . $set_dir_relative;
498  ilUtil::makeDirParents($set_dir_absolute);
499  $this->log->debug("dir: " . $set_dir_absolute);
500 
501  $this->log->debug("init exporter");
502  $exp->init();
503 
504  // process head dependencies
505  $this->log->debug("process head dependencies for " . $a_entity);
506  $sequence = $exp->getXmlExportHeadDependencies($a_entity, $a_target_release, $a_id);
507  foreach ($sequence as $s) {
508  $comp = explode("/", $s["component"]);
509  $exp_class = "il" . $comp[1] . "Exporter";
510  $s = $this->processExporter(
511  $s["component"],
512  $exp_class,
513  $s["entity"],
514  $a_target_release,
515  $s["ids"]
516  );
517  if (!$s) {
518  $success = false;
519  }
520  }
521 
522  // write export.xml file
523  $export_writer = new ilXmlWriter();
524  $export_writer->xmlHeader();
525 
526  $sv = $exp->determineSchemaVersion($a_entity, $a_target_release);
527  $this->log->debug("schema version for entity: $a_entity, target release: $a_target_release");
528  $this->log->debug("...is: " . $sv["schema_version"] . ", namespace: " . $sv["namespace"] .
529  ", xsd file: " . $sv["xsd_file"] . ", uses_dataset: " . ((int) $sv["uses_dataset"]));
530 
531  $attribs = array("InstallationId" => IL_INST_ID,
532  "InstallationUrl" => ILIAS_HTTP_PATH,
533  "Entity" => $a_entity, "SchemaVersion" => $sv["schema_version"], "TargetRelease" => $a_target_release,
534  "xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance",
535  "xmlns:exp" => "http://www.ilias.de/Services/Export/exp/4_1",
536  "xsi:schemaLocation" => "http://www.ilias.de/Services/Export/exp/4_1 " . ILIAS_HTTP_PATH . "/xml/ilias_export_4_1.xsd"
537  );
538  if ($sv["namespace"] != "" && $sv["xsd_file"] != "") {
539  $attribs["xsi:schemaLocation"].= " " . $sv["namespace"] . " " .
540  ILIAS_HTTP_PATH . "/xml/" . $sv["xsd_file"];
541  $attribs["xmlns"] = $sv["namespace"];
542  }
543  if ($sv["uses_dataset"]) {
544  $attribs["xsi:schemaLocation"].= " " .
545  "http://www.ilias.de/Services/DataSet/ds/4_3 " . ILIAS_HTTP_PATH . "/xml/ilias_ds_4_3.xsd";
546  $attribs["xmlns:ds"] = "http://www.ilias.de/Services/DataSet/ds/4_3";
547  }
548 
549 
550  $export_writer->xmlStartTag('exp:Export', $attribs);
551 
552  $dir_cnt = 1;
553  foreach ($a_id as $id) {
554  $exp->setExportDirectories(
555  $set_dir_relative . "/expDir_" . $dir_cnt,
556  $set_dir_absolute . "/expDir_" . $dir_cnt
557  );
558  $export_writer->xmlStartTag('exp:ExportItem', array("Id" => $id));
559  //$xml = $exp->getXmlRepresentation($a_entity, $a_target_release, $id);
560  $xml = $exp->getXmlRepresentation($a_entity, $sv["schema_version"], $id);
561  $export_writer->appendXml($xml);
562  $export_writer->xmlEndTag('exp:ExportItem');
563  $dir_cnt++;
564  }
565 
566  $export_writer->xmlEndTag('exp:Export');
567  $export_writer->xmlDumpFile($set_dir_absolute . "/export.xml", false);
568 
569  $this->manifest_writer->xmlElement(
570  "ExportFile",
571  array("Component" => $a_comp, "Path" => $set_dir_relative . "/export.xml")
572  );
573 
574  // process tail dependencies
575  $this->log->debug("process tail dependencies of " . $a_entity);
576  $sequence = $exp->getXmlExportTailDependencies($a_entity, $a_target_release, $a_id);
577  foreach ($sequence as $s) {
578  $comp = explode("/", $s["component"]);
579  $exp_class = "il" . $comp[1] . "Exporter";
580  $s = $this->processExporter(
581  $s["component"],
582  $exp_class,
583  $s["entity"],
584  $a_target_release,
585  $s["ids"]
586  );
587  if (!$s) {
588  $success = false;
589  }
590  }
591 
592  $this->log->debug("returning " . ((int) $success) . " for " . $a_entity);
593  return $success;
594  }
595 }
$files
Definition: add-vimline.php:18
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)
global $ilErr
Definition: raiseError.php:16
static $new_file_structure
const ILIAS_VERSION_NUMERIC
$type
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!)
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
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
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
$xml
Definition: metadata.php:240
$success
Definition: Utf8Test.php:86
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.
date( 'd-M-Y', $objPHPExcel->getProperties() ->getCreated())
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
Create styles array
The data for the language used.
static _lookupType($a_id, $a_reference=false)
lookup object type
static getDataDir()
get data directory (outside webspace)
global $lng
Definition: privfeed.php:17
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.
Add data(end) time
Method that wraps PHPs time in order to allow simulations with the workflow.
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
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.