ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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 ilFileXMLParser(& $file, $a_xml_data, $obj_id = -1, $mode = 0)
87  {
88  parent::ilSaxParser();
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 = array();
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.
static normalizeRelativePath($path)
Normalize relative directories in a path.
startParsing()
stores xml data in array
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
_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.
Class to report exception.
ilFileXMLParser(& $file, $a_xml_data, $obj_id=-1, $mode=0)
Constructor.
$filename
Definition: buildRTE.php:89
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...
$path
Definition: index.php:22
static getLogger($a_component_id)
Get component logger.
fastGunzip($in, $out)
fast uncompressing the file with the zlib-extension without memory consumption
$GLOBALS['PHPCAS_CLIENT']
This global variable is used by the interface class phpCAS.
Definition: CAS.php:276
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...