ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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 
16 include_once './Services/Xml/classes/class.ilSaxParser.php';
17 include_once 'Modules/File/classes/class.ilFileException.php';
18 include_once 'Services/Utilities/classes/class.ilFileUtils.php';
19 
21 {
22  public static $CONTENT_NOT_COMPRESSED = 0;
23  public static $CONTENT_GZ_COMPRESSED = 1;
24  public static $CONTENT_ZLIB_COMPRESSED = 2;
25  public static $CONTENT_COPY = 4;
26  // begin-patch fm
27  public static $CONTENT_REST = 5;
28  // end-patch fm
34  public $file;
41  public $obj_id;
47  public $result;
53  public $mode;
59  //var $content;
60 
66  public $tmpFilename;
67 
68 
78  public function __construct(&$file, $a_xml_data, $obj_id = -1, $mode = 0)
79  {
80  parent::__construct();
81  $this->file = $file;
82  $this->setXMLContent($a_xml_data);
83  $this->obj_id = $obj_id;
84  $this->result = false;
85  $this->mode = $mode;
86  }
87 
88 
94  public function setImportDirectory($a_val)
95  {
96  $this->importDirectory = $a_val;
97  }
98 
99 
105  public function getImportDirectory()
106  {
107  return $this->importDirectory;
108  }
109 
110 
118  public function setHandlers($a_xml_parser)
119  {
120  xml_set_object($a_xml_parser, $this);
121  xml_set_element_handler($a_xml_parser, 'handlerBeginTag', 'handlerEndTag');
122  xml_set_character_data_handler($a_xml_parser, 'handlerCharacterData');
123  }
124 
125 
136  public function handlerBeginTag($a_xml_parser, $a_name, $a_attribs)
137  {
138  global $DIC;
139  $ilErr = $DIC['ilErr'];
140 
141  global $DIC;
142  $ilLog = $DIC['ilLog'];
143 
144  switch ($a_name) {
145  case 'File':
146  if (isset($a_attribs["obj_id"])) {
147  $read_obj_id = ilUtil::__extractId($a_attribs["obj_id"], IL_INST_ID);
148  if ($this->obj_id != -1 && (int) $read_obj_id != -1 && (int) $this->obj_id != (int) $read_obj_id) {
149  throw new ilFileException("Object IDs (xml $read_obj_id and argument " . $this->obj_id . ") do not match!", ilFileException::$ID_MISMATCH);
150  }
151  }
152  if (isset($a_attribs["type"])) {
153  $this->file->setFileType($a_attribs["type"]);
154  }
155  $this->file->setVersion($this->file->getVersion() + 1);
156  break;
157  case 'Content':
158  $this->tmpFilename = ilUtil::ilTempnam();
160  $this->isReadingFile = true;
161  #echo $a_attribs["mode"];
162  if (isset($a_attribs["mode"])) {
163  if ($a_attribs["mode"] == "GZIP") {
164  if (!function_exists("gzread")) {
165  throw new ilFileException("Deflating with gzip is not supported", ilFileException::$ID_DEFLATE_METHOD_MISMATCH);
166  }
167 
169  } elseif ($a_attribs["mode"] == "ZLIB") {
170  if (!function_exists("gzuncompress")) {
171  throw new ilFileException("Deflating with zlib (compress/uncompress) is not supported", ilFileException::$ID_DEFLATE_METHOD_MISMATCH);
172  }
173 
175  } elseif ($a_attribs["mode"] == "COPY") {
176  $this->mode = ilFileXMLParser::$CONTENT_COPY;
177  } // begin-patch fm
178  elseif ($a_attribs['mode'] == 'REST') {
179  $this->mode = ilFileXMLParser::$CONTENT_REST;
180  }
181  // end-patch fm
182  }
183  }
184  }
185 
186 
193  public function handlerEndTag($a_xml_parser, $a_name)
194  {
195  $this->cdata = trim($this->cdata);
196 
197  $GLOBALS['DIC']['ilLog']->write(__METHOD__ . ': ' . $this->cdata);
198 
199  switch ($a_name) {
200  case 'File':
201  $this->result = true;
202  break;
203  case 'Filename':
204  if (strlen($this->cdata) == 0) {
205  throw new ilFileException("Filename ist missing!");
206  }
207 
208  $this->file->setFilename(basename(self::normalizeRelativePath($this->cdata)));
209  $this->file->setTitle($this->cdata);
210 
211  break;
212  case 'Title':
213  $this->file->setTitle(trim($this->cdata));
214  break;
215  case 'Description':
216  $this->file->setDescription(trim($this->cdata));
217  break;
218  case 'Rating':
219  $this->file->setRating((bool) $this->cdata);
220  break;
221  case 'Content':
222  $GLOBALS['DIC']['ilLog']->write($this->mode);
223  $this->isReadingFile = false;
224  $baseDecodedFilename = ilUtil::ilTempnam();
225  if ($this->mode == ilFileXMLParser::$CONTENT_COPY) {
226  $this->tmpFilename = $this->getImportDirectory() . "/" . self::normalizeRelativePath($this->cdata);
227  } // begin-patch fm
228  elseif ($this->mode == ilFileXMLParser::$CONTENT_REST) {
229  include_once './Services/WebServices/Rest/classes/class.ilRestFileStorage.php';
230  $storage = new ilRestFileStorage();
231  $this->tmpFilename = $storage->getStoredFilePath(self::normalizeRelativePath($this->cdata));
232  if (!ilFileUtils::fastBase64Decode($this->tmpFilename, $baseDecodedFilename)) {
233  throw new ilFileException("Base64-Decoding failed", ilFileException::$DECOMPRESSION_FAILED);
234  }
235  $this->tmpFilename = $baseDecodedFilename;
236  } // end-patch fm
237  else {
238  if (!ilFileUtils::fastBase64Decode($this->tmpFilename, $baseDecodedFilename)) {
239  throw new ilFileException("Base64-Decoding failed", ilFileException::$DECOMPRESSION_FAILED);
240  }
241  if ($this->mode == ilFileXMLParser::$CONTENT_GZ_COMPRESSED) {
242  if (!ilFileUtils::fastGunzip($baseDecodedFilename, $this->tmpFilename)) {
243  throw new ilFileException("Deflating with fastzunzip failed", ilFileException::$DECOMPRESSION_FAILED);
244  }
245  unlink($baseDecodedFilename);
246  } elseif ($this->mode == ilFileXMLParser::$CONTENT_ZLIB_COMPRESSED) {
247  if (!ilFileUtils::fastGunzip($baseDecodedFilename, $this->tmpFilename)) {
248  throw new ilFileException("Deflating with fastDecompress failed", ilFileException::$DECOMPRESSION_FAILED);
249  }
250  unlink($baseDecodedFilename);
251  } else {
252  $this->tmpFilename = $baseDecodedFilename;
253  }
254  }
255  //$this->content = $content;
256  // see #17211
257  if (is_file($this->tmpFilename)) {
258  $this->file->setFileSize(filesize($this->tmpFilename)); // strlen($this->content));
259  }
260 
261  // if no file type is given => lookup mime type
262  if (!$this->file->getFileType()) {
263  global $DIC;
264  $ilLog = $DIC['ilLog'];
265 
266  #$ilLog->write(__METHOD__.': Trying to detect mime type...');
267  include_once('./Services/Utilities/classes/class.ilFileUtils.php');
268  $this->file->setFileType(ilFileUtils::_lookupMimeType($this->tmpFilename));
269  }
270 
271  break;
272  }
273 
274  $this->cdata = '';
275 
276  return;
277  }
278 
279 
286  public function handlerCharacterData($a_xml_parser, $a_data)
287  {
288  if ($a_data != "\n") {
289  // begin-patch fm
290  if ($this->isReadingFile && $this->mode != ilFileXMLParser::$CONTENT_COPY && $this->mode != ilFileXMLParser::$CONTENT_REST) { // begin-patch fm
291  $handle = fopen($this->tmpFilename, "a");
292  fwrite($handle, $a_data);
293  fclose($handle);
294  } else {
295  $this->cdata .= $a_data;
296  }
297  }
298  }
299 
300 
306  public function setFileContents()
307  {
308  if (!file_exists($this->tmpFilename)) {
309  ilLoggerFactory::getLogger('file')->error(__METHOD__ . ' "' . $this->tmpFilename . '" file not found.');
310 
311  return;
312  }
313 
314  if (filesize($this->tmpFilename) == 0) {
315  return;
316  }
317 
318  $filedir = $this->file->getDirectory($this->file->getVersion());
319 
320  if (!is_dir($filedir)) {
321  $this->file->createDirectory();
322  ilUtil::makeDir($filedir);
323  }
324 
325  $filename = $filedir . "/" . $this->file->getFileName();
326 
327  if (file_exists($filename)) {
328  unlink($filename);
329  }
330 
331  return ilFileUtils::rename($this->tmpFilename, $filename);
332  }
333 
334 
340  public function updateFileContents()
341  {
342  if ($this->setFileContents()) {
343  require_once("./Services/History/classes/class.ilHistory.php");
344  ilHistory::_createEntry($this->file->getId(), "replace", $this->file->getFilename() . "," . $this->file->getVersion());
345  $this->file->addNewsNotification("file_updated");
346  }
347  }
348 
349 
357  public function start()
358  {
359  $this->startParsing();
360 
361  return $this->result > 0;
362  }
363 
364 
377  public static function normalizeRelativePath($path)
378  {
379  $path = str_replace('\\', '/', $path);
380 
381  while (preg_match('#\p{C}+|^\./#u', $path)) {
382  $path = preg_replace('#\p{C}+|^\./#u', '', $path);
383  }
384 
385  $parts = [];
386  foreach (explode('/', $path) as $part) {
387  switch ($part) {
388  case '':
389  case '.':
390  break;
391  case '..':
392  array_pop($parts);
393  break;
394  default:
395  $parts[] = $part;
396  break;
397  }
398  }
399 
400  return implode('/', $parts);
401  }
402 }
setImportDirectory($a_val)
Set import directory.
global $ilErr
Definition: raiseError.php:16
static normalizeRelativePath($path)
Normalize relative directories in a path.
global $DIC
Definition: saml.php:7
startParsing()
stores xml data in array
__construct(&$file, $a_xml_data, $obj_id=-1, $mode=0)
Constructor.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
Exercise XML Parser which completes/updates a given file by an xml string.
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.
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
Class to report exception.
Reload workbook from saved file
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.
static 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...