ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilFileXMLParser.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 
17 include_once './Services/Xml/classes/class.ilSaxParser.php';
18 include_once 'Modules/File/classes/class.ilFileException.php';
19 include_once 'Services/Utilities/classes/class.ilFileUtils.php';
20 
21 
23 {
27  static $CONTENT_COPY = 4;
28  // begin-patch fm
29  static $CONTENT_REST = 5;
30  // end-patch fm
31 
37  var $file;
38 
45  var $obj_id;
46 
47 
53  var $result;
54 
60  var $mode;
61 
62 
68  //var $content;
69 
76 
77 
86  function __construct(& $file, $a_xml_data, $obj_id = -1, $mode = 0)
87  {
88  parent::__construct();
89  $this->file = $file;
90  $this->setXMLContent($a_xml_data);
91  $this->obj_id = $obj_id;
92  $this->result = false;
93  $this->mode = $mode;
94  }
95 
101  function setImportDirectory($a_val)
102  {
103  $this->importDirectory = $a_val;
104  }
105 
112  {
113  return $this->importDirectory;
114  }
121  function setHandlers($a_xml_parser)
122  {
123  xml_set_object($a_xml_parser,$this);
124  xml_set_element_handler($a_xml_parser,'handlerBeginTag','handlerEndTag');
125  xml_set_character_data_handler($a_xml_parser,'handlerCharacterData');
126  }
127 
137  function handlerBeginTag($a_xml_parser,$a_name,$a_attribs)
138  {
139  global $ilErr;
140 
141  global $ilLog;
142 
143  switch($a_name)
144  {
145  case 'File':
146  if (isset($a_attribs["obj_id"]))
147  {
148  $read_obj_id = ilUtil::__extractId($a_attribs["obj_id"], IL_INST_ID);
149  if ($this->obj_id != -1 && (int) $read_obj_id != -1 && (int) $this->obj_id != (int) $read_obj_id)
150  {
151  throw new ilFileException ("Object IDs (xml $read_obj_id and argument ".$this->obj_id.") do not match!", ilFileException::$ID_MISMATCH);
152  }
153  }
154  if (isset($a_attribs["type"]))
155  {
156  $this->file->setFileType($a_attribs["type"]);
157  }
158  break;
159  case 'Content':
160  $this->tmpFilename = ilUtil::ilTempnam();
162  $this->isReadingFile = true;
163 #echo $a_attribs["mode"];
164  if (isset($a_attribs["mode"]))
165  {
166  if($a_attribs["mode"] == "GZIP")
167  {
168  if (!function_exists("gzread"))
169  throw new ilFileException ("Deflating with gzip is not supported", ilFileException::$ID_DEFLATE_METHOD_MISMATCH);
170 
172  }
173  elseif ($a_attribs["mode"] == "ZLIB")
174  {
175  if (!function_exists("gzuncompress"))
176  throw new ilFileException ("Deflating with zlib (compress/uncompress) is not supported", ilFileException::$ID_DEFLATE_METHOD_MISMATCH);
177 
179  }
180  elseif ($a_attribs["mode"] == "COPY")
181  {
182  $this->mode = ilFileXMLParser::$CONTENT_COPY;
183  }
184  // begin-patch fm
185  elseif($a_attribs['mode'] == 'REST')
186  {
187  $this->mode = ilFileXMLParser::$CONTENT_REST;
188  }
189  // end-patch fm
190  }
191  }
192  }
193 
194 
195 
202  function handlerEndTag($a_xml_parser,$a_name)
203  {
204  $this->cdata = trim($this->cdata);
205 
206  $GLOBALS['ilLog']->write(__METHOD__.': '.$this->cdata);
207 
208  switch($a_name)
209  {
210  case 'File':
211  $this->result = true;
212  break;
213  case 'Filename':
214  if (strlen($this->cdata) == 0)
215  throw new ilFileException("Filename ist missing!");
216 
217  $this->file->setFilename(basename(self::normalizeRelativePath($this->cdata)));
218  $this->file->setTitle($this->cdata);
219 
220  break;
221  case 'Title':
222  $this->file->setTitle(trim($this->cdata));
223  break;
224  case 'Description':
225  $this->file->setDescription(trim($this->cdata));
226  break;
227  case 'Rating':
228  $this->file->setRating((bool)$this->cdata);
229  break;
230  case 'Content':
231  $GLOBALS['ilLog']->write($this->mode);
232  $this->isReadingFile = false;
233  $baseDecodedFilename = ilUtil::ilTempnam();
234  if ($this->mode == ilFileXMLParser::$CONTENT_COPY)
235  {
236  $this->tmpFilename = $this->getImportDirectory()."/".self::normalizeRelativePath($this->cdata);
237  }
238  // begin-patch fm
239  elseif($this->mode == ilFileXMLParser::$CONTENT_REST)
240  {
241  include_once './Services/WebServices/Rest/classes/class.ilRestFileStorage.php';
242  $storage = new ilRestFileStorage();
243  $this->tmpFilename = $storage->getStoredFilePath(self::normalizeRelativePath($this->cdata));
244  if(!ilFileUtils::fastBase64Decode($this->tmpFilename, $baseDecodedFilename))
245  {
246  throw new ilFileException("Base64-Decoding failed", ilFileException::$DECOMPRESSION_FAILED);
247  }
248  $this->tmpFilename = $baseDecodedFilename;
249  }
250  // end-patch fm
251  else
252  {
253  if (!ilFileUtils::fastBase64Decode($this->tmpFilename, $baseDecodedFilename))
254  {
255  throw new ilFileException ("Base64-Decoding failed", ilFileException::$DECOMPRESSION_FAILED);
256  }
257  if ($this->mode == ilFileXMLParser::$CONTENT_GZ_COMPRESSED)
258  {
259  if (!ilFileUtils::fastGunzip ($baseDecodedFilename, $this->tmpFilename))
260  {
261  throw new ilFileException ("Deflating with fastzunzip failed", ilFileException::$DECOMPRESSION_FAILED);
262  }
263  unlink ($baseDecodedFilename);
264  }
265  elseif ($this->mode == ilFileXMLParser::$CONTENT_ZLIB_COMPRESSED)
266  {
267  if (!ilFileUtils::fastGunzip ($baseDecodedFilename, $this->tmpFilename))
268  {
269  throw new ilFileException ("Deflating with fastDecompress failed", ilFileException::$DECOMPRESSION_FAILED);
270  }
271  unlink ($baseDecodedFilename);
272  }
273  else
274  {
275  $this->tmpFilename = $baseDecodedFilename;
276  }
277  }
278  //$this->content = $content;
279  // see #17211
280  if (is_file($this->tmpFilename))
281  {
282  $this->file->setFileSize(filesize($this->tmpFilename)); // strlen($this->content));
283  }
284 
285  // if no file type is given => lookup mime type
286  if(!$this->file->getFileType())
287  {
288  global $ilLog;
289 
290  #$ilLog->write(__METHOD__.': Trying to detect mime type...');
291  include_once('./Services/Utilities/classes/class.ilFileUtils.php');
292  $this->file->setFileType(ilFileUtils::_lookupMimeType($this->tmpFilename));
293  }
294 
295  break;
296  }
297 
298  $this->cdata = '';
299 
300  return;
301  }
302 
309  function handlerCharacterData($a_xml_parser,$a_data)
310  {
311  if($a_data != "\n")
312  {
313  // begin-patch fm
314  if ($this->isReadingFile && $this->mode != ilFileXMLParser::$CONTENT_COPY && $this->mode != ilFileXMLParser::$CONTENT_REST)
315  // begin-patch fm
316  {
317  $handle = fopen($this->tmpFilename, "a");
318  fwrite ($handle, $a_data);
319  fclose ($handle);
320  } else
321  $this->cdata .= $a_data;
322  }
323  }
324 
330  public function setFileContents ()
331  {
332  if(!file_exists($this->tmpFilename))
333  {
334  ilLoggerFactory::getLogger('file')->error(__METHOD__.' "'.$this->tmpFilename. '" file not found.');
335  return;
336  }
337 
338  if (filesize ($this->tmpFilename) == 0) {
339  return;
340  }
341 
342  $filedir = $this->file->getDirectory($this->file->getVersion());
343 
344  if (!is_dir($filedir))
345  {
346  $this->file->createDirectory();
347  ilUtil::makeDir($filedir);
348  }
349 
350  $filename = $filedir."/".$this->file->getFileName();
351 
352  if (file_exists($filename))
353  unlink($filename);
354  require_once('./Services/Utilities/classes/class.ilFileUtils.php');
355  return ilFileUtils::rename($this->tmpFilename, $filename);
356  }
357 
358 
364  public function updateFileContents ()
365  {
366  if ($this->setFileContents())
367  {
368  require_once("./Services/History/classes/class.ilHistory.php");
369  ilHistory::_createEntry($this->file->getId(), "replace", $this->file->getFilename().",".$this->file->getVersion());
370  $this->file->addNewsNotification("file_updated");
371  }
372  }
373 
381  public function start () {
382  $this->startParsing();
383  return $this->result > 0;
384  }
385 
386 
399  public static function normalizeRelativePath($path) {
400  $path = str_replace('\\', '/', $path);
401 
402  while (preg_match('#\p{C}+|^\./#u', $path)) {
403  $path = preg_replace('#\p{C}+|^\./#u', '', $path);
404  }
405 
406  $parts = [];
407  foreach (explode('/', $path) as $part) {
408  switch ($part) {
409  case '':
410  case '.':
411  break;
412  case '..':
413  array_pop($parts);
414  break;
415  default:
416  $parts[] = $part;
417  break;
418  }
419  }
420 
421  return implode('/', $parts);
422  }
423 }
setImportDirectory($a_val)
Set import directory.
global $ilErr
Definition: raiseError.php:16
$path
Definition: aliased.php:25
static normalizeRelativePath($path)
Normalize relative directories in a path.
startParsing()
stores xml data in array
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
Exercise XML Parser which completes/updates a given file by an xml string.
handlerEndTag($a_xml_parser, $a_name)
handler for end of element
Base class for sax-based expat parsing extended classes need to overwrite the method setHandlers and ...
start()
starts parsing an changes object by side effect.
static _lookupMimeType($a_file)
static rename($a_source, $a_target)
Rename a file.
handlerCharacterData($a_xml_parser, $a_data)
handler for character data
__construct(& $file, $a_xml_data, $obj_id=-1, $mode=0)
Constructor.
Class to report exception.
Reload workbook from saved file
static _createEntry($a_obj_id, $a_action, $a_info_params="", $a_obj_type="", $a_user_comment="", $a_update_last=false)
Creates a new history entry for an object.
static makeDir($a_dir)
creates a new directory and inherits all filesystem permissions of the parent directory You may pass ...
setHandlers($a_xml_parser)
set event handlers
static ilTempnam($a_temp_path=null)
Create a temporary file in an ILIAS writable directory.
File storage handling.
fastBase64Decode($filein, $fileout)
decodes base encoded file row by row to prevent memory exhaust
updateFileContents()
update file according to filename and version and create history entry has to be called after (!) fil...
static getLogger($a_component_id)
Get component logger.
fastGunzip($in, $out)
fast uncompressing the file with the zlib-extension without memory consumption
getImportDirectory()
Get import directory.
setXMLContent($a_xml_content)
static __extractId($ilias_id, $inst_id)
extract ref id from role title, e.g.
handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
handler for begin of element
setFileContents()
update file according to filename and version, does not update history has to be called after (!) fil...