ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObjBibliographic.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 require_once "Services/Object/classes/class.ilObject2.php";
6 require_once "Modules/Bibliographic/classes/class.ilBibliographicEntry.php";
7 
8 /* Declaring namespace for library RISReader */
9 use \LibRIS\RISReader;
10 
20 
22 
28  protected $filename;
34  protected $entries;
40  protected $overviewModels;
46  protected $is_online;
47 
48 
54  public function initType() {
55  $this->type = "bibl";
56  }
57 
58 
66  public function __construct($existant_bibl_id = 0) {
67  if ($existant_bibl_id) {
68  $this->setId($existant_bibl_id);
69  $this->doRead();
70  }
71 
72  parent::__construct($existant_bibl_id, false);
73  }
74 
75 
81  function doCreate() {
82  global $ilDB;
83 
84  $ilDB->manipulate("INSERT INTO il_bibl_data " . "(id, filename, is_online) VALUES ("
85  . $ilDB->quote($this->getId(), "integer") . "," . // id
86  $ilDB->quote($this->getFilename(), "text") . "," . // filename
87  $ilDB->quote($this->getOnline(), "integer") . // is_online
88  ")");
89  }
90 
91 
92  function doRead() {
93 
94  global $ilDB;
95  $set = $ilDB->query("SELECT * FROM il_bibl_data " . " WHERE id = " . $ilDB->quote($this->getId(), "integer"));
96  while ($rec = $ilDB->fetchAssoc($set)) {
97  if (! $this->getFilename()) {
98  $this->setFilename($rec["filename"]);
99  }
100  $this->setOnline($rec['is_online']);
101  }
102  }
103 
104 
108  function doUpdate() {
109  global $ilDB;
110 
111  if (! empty($_FILES['bibliographic_file']['name'])) {
112  $this->deleteFile();
113  $this->moveFile();
114  }
115  // Delete the object, but leave the db table 'il_bibl_data' for being able to update it using WHERE, and also leave the file
116  $this->doDelete(true, true);
117 
118  $ilDB->manipulate("UPDATE il_bibl_data SET " . "filename = " . $ilDB->quote($this->getFilename(), "text") . ", "
119  . // filename
120  "is_online = " . $ilDB->quote($this->getOnline(), "integer") . // is_online
121  " WHERE id = " . $ilDB->quote($this->getId(), "integer"));
122 
123  $this->writeSourcefileEntriesToDb($this);
124  }
125 
126 
127  /*
128  * Delete data from db
129  */
130  function doDelete($leave_out_il_bibl_data = false, $leave_out_delete_file = false) {
131  global $ilDB;
132 
133  if (! $leave_out_delete_file) {
134  $this->deleteFile();
135  }
136 
137  //il_bibl_attribute
138  $ilDB->manipulate("DELETE FROM il_bibl_attribute WHERE il_bibl_attribute.entry_id IN "
139  . "(SELECT il_bibl_entry.id FROM il_bibl_entry WHERE il_bibl_entry.data_id = "
140  . $ilDB->quote($this->getId(), "integer") . ");");
141 
142  //il_bibl_entry
143  $ilDB->manipulate("DELETE FROM il_bibl_entry WHERE data_id = " . $ilDB->quote($this->getId(), "integer"));
144 
145  if (! $leave_out_il_bibl_data) {
146  //il_bibl_data
147  $ilDB->manipulate("DELETE FROM il_bibl_data WHERE id = " . $ilDB->quote($this->getId(), "integer"));
148  }
149 
150  // delete history entries
151  require_once("./Services/History/classes/class.ilHistory.php");
153  }
154 
155 
159  public function getFileDirectory() {
160  return ilUtil::getDataDir() . DIRECTORY_SEPARATOR . $this->getType() . DIRECTORY_SEPARATOR . $this->getId();
161  }
162 
163 
164  public function moveFile($file_to_copy = false) {
165 
166  $target_dir = $this->getFileDirectory();
167 
168  if (! is_dir($target_dir)) {
169  ilUtil::makeDirParents($target_dir);
170  }
171 
172  if ($_FILES['bibliographic_file']['name']) {
173  $filename = $_FILES['bibliographic_file']['name'];
174  } elseif ($file_to_copy) {
175  //file is not uploaded, but a clone is made out of another bibl
176  $split_path = explode(DIRECTORY_SEPARATOR, $file_to_copy);
177  $filename = $split_path[sizeof($split_path) - 1];
178  } else {
179  throw new Exception("Either a file must be delivered via \$_POST/\$_FILE or the file must be delivered via the method argument file_to_copy");
180  }
181 
182  $target_full_filename = $target_dir . DIRECTORY_SEPARATOR . $filename;
183 
184  //If there is no file_to_copy (which is used for clones), copy the file from the temporary upload directory (new creation of object).
185  //Therefore, a warning predicates nothing and can be suppressed.
186  if (@! copy($file_to_copy, $target_full_filename)) {
187  ilUtil::moveUploadedFile($_FILES['bibliographic_file']['tmp_name'], $_FILES['bibliographic_file']['name'], $target_full_filename);
188  }
189 
190  $this->setFilename($filename);
191  ilUtil::sendSuccess($this->lng->txt("object_added"), true);
192  }
193 
194 
195  function deleteFile() {
196  $path = $this->getFilePath(true);
198  }
199 
200 
206  public function getFilePath($without_filename = false) {
207  global $ilDB;
208 
209  $set = $ilDB->query("SELECT filename FROM il_bibl_data " . " WHERE id = "
210  . $ilDB->quote($this->getId(), "integer"));
211 
212  $rec = $ilDB->fetchAssoc($set);
213  {
214  if ($without_filename) {
215  return substr($rec['filename'], 0, strrpos($rec['filename'], DIRECTORY_SEPARATOR));
216  } else {
217  return $rec['filename'];
218  }
219  }
220  }
221 
222 
223  public function setFilename($filename) {
224  $this->filename = $filename;
225  }
226 
227 
228  public function getFilename() {
229  return $this->filename;
230  }
231 
232 
236  public function getFileAbsolutePath() {
237  return $this->getFileDirectory() . DIRECTORY_SEPARATOR . $this->getFilename();
238  }
239 
240 
241  public function getFiletype() {
242  //return bib for filetype .bibtex:
243  if (strtolower(substr($this->getFilename(), - 6)) == "bibtex") {
244  return "bib";
245  }
246 
247  //else return its true filetype
248  return strtolower(substr($this->getFilename(), - 3));
249  }
250 
251 
252  static function __getAllOverviewModels() {
253  global $ilDB;
254 
255  $set = $ilDB->query('SELECT * FROM il_bibl_overview_model');
256  while ($rec = $ilDB->fetchAssoc($set)) {
257  if ($rec['literature_type']) {
258  $overviewModels[$rec['filetype']][$rec['literature_type']] = $rec['pattern'];
259  } else {
260  $overviewModels[$rec['filetype']] = $rec['pattern'];
261  }
262  }
263 
264  return $overviewModels;
265  }
266 
267 
275  protected static function __force_rmdir($path) {
276  if (! file_exists($path)) {
277  return false;
278  }
279 
280  if (is_file($path) || is_link($path)) {
281  return unlink($path);
282  }
283 
284  if (is_dir($path)) {
285  $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
286 
287  $result = true;
288 
289  $dir = new DirectoryIterator($path);
290 
291  foreach ($dir as $file) {
292  if (! $file->isDot()) {
293  $result &= self::__force_rmdir($path . $file->getFilename(), false);
294  }
295  }
296 
297  $result &= rmdir($path);
298 
299  return $result;
300  }
301  }
302 
303 
304  static function __readRisFile($full_filename) {
305 
306  self::__setCharsetToUtf8($full_filename);
307 
308  require_once "./Modules/Bibliographic/lib/LibRIS/src/LibRIS/RISReader.php";
309 
310  $ris_reader = new RISReader();
311  $ris_reader->parseFile($full_filename);
312 
313  return $ris_reader->getRecords();
314  }
315 
316 
317  static function __readBibFile($full_filename) {
318 
319  self::__setCharsetToUtf8($full_filename);
320 
321  require_once 'Modules/Bibliographic/lib/PEAR_BibTex_1.0.0RC5/Structures/BibTex.php';
322 
323  $bibtex_reader = new Structures_BibTex();
324 
325  //Loading and parsing the file example.bib
326  $bibtex_reader->loadFile($full_filename);
327 
328  //replace bibtex special chars with the real characters
329  $bibtex_reader->content = self::__convertBibSpecialChars($bibtex_reader->content);
330 
331  $bibtex_reader->setOption('extractAuthor', false);
332  $bibtex_reader->parse();
333 
334  // Remove library-bug: if there is no cite, the library mixes up the key for the type and the first attribute.
335  // It also shows an empty and therefore unwanted cite in the array.
336  //
337  // The cite is the text coming right after the type. Example:
338  // @book {cite,
339  // author = { "...."},
340 
341  foreach ($bibtex_reader->data as $key => $entry) {
342  if (empty($entry['cite'])) {
343  unset($bibtex_reader->data[$key]['cite']);
344 
345  foreach ($entry as $attr_key => $attribute) {
346  if (strpos($attr_key, '{') !== false) {
347  unset($bibtex_reader->data[$key][$attr_key]);
348  $attr_key_exploaded = explode('{', $attr_key);
349  $bibtex_reader->data[$key]['entryType'] = trim($attr_key_exploaded[0]);
350  $bibtex_reader->data[$key][trim($attr_key_exploaded[1])] = $attribute;
351  }
352  }
353  }
354 
355  // formating the author to the following type of string
356  // Smith, John / Comte, Gabriel / von Gunten Jr, Thomas
357  foreach ($entry as $attr_key => $attribute) {
358  if ($attr_key == 'author' && is_array($attribute)) {
359  $attribute_string = array();
360  foreach ($attribute as $author_key => $author) {
361  $lastname = array($author['von'], $author['last'], $author['jr']);
362  $attribute_string[$author_key] = implode(' ', array_filter($lastname));
363  if(!empty($author['first'])){
364  $attribute_string[$author_key] .= ', ' . $author['first'];
365  }
366  }
367  $bibtex_reader->data[$key][$attr_key] = implode(' / ', $attribute_string);
368  }
369  }
370  }
371 
372  return $bibtex_reader->data;
373  }
374 
375 
376  static function __setCharsetToUtf8($full_filename) {
377  //If file charset does not seem to be Unicode, we assume that it is ISO-8859-1, and convert it to UTF-8.
378  $filedata = file_get_contents($full_filename);
379  if (strlen($filedata) == strlen(utf8_decode($filedata))) {
380  // file charset is not UTF-8
381  $filedata = mb_convert_encoding($filedata, 'UTF-8', 'ISO-8859-1');
382  file_put_contents($full_filename, $filedata);
383  }
384  }
385 
386 
395  static function __convertBibSpecialChars($file_content) {
396 
397  $bibtex_special_chars['ä'] = '{\"a}';
398  $bibtex_special_chars['ë'] = '{\"e}';
399  $bibtex_special_chars['ï'] = '{\"i}';
400  $bibtex_special_chars['ö'] = '{\"o}';
401  $bibtex_special_chars['ü'] = '{\"u}';
402 
403  $bibtex_special_chars['Ä'] = '{\"A}';
404  $bibtex_special_chars['Ë'] = '{\"E}';
405  $bibtex_special_chars['Ï'] = '{\"I}';
406  $bibtex_special_chars['Ö'] = '{\"O}';
407  $bibtex_special_chars['Ü'] = '{\"U}';
408 
409  $bibtex_special_chars['â'] = '{\^a}';
410  $bibtex_special_chars['ê'] = '{\^e}';
411  $bibtex_special_chars['î'] = '{\^i}';
412  $bibtex_special_chars['ô'] = '{\^o}';
413  $bibtex_special_chars['û'] = '{\^u}';
414 
415  $bibtex_special_chars['Â'] = '{\^A}';
416  $bibtex_special_chars['Ê'] = '{\^E}';
417  $bibtex_special_chars['Î'] = '{\^I}';
418  $bibtex_special_chars['Ô'] = '{\^O}';
419  $bibtex_special_chars['Û'] = '{\^U}';
420 
421  $bibtex_special_chars['à'] = '{\`a}';
422  $bibtex_special_chars['è'] = '{\`e}';
423  $bibtex_special_chars['ì'] = '{\`i}';
424  $bibtex_special_chars['ò'] = '{\`o}';
425  $bibtex_special_chars['ù'] = '{\`u}';
426 
427  $bibtex_special_chars['À'] = '{\`A}';
428  $bibtex_special_chars['È'] = '{\`E}';
429  $bibtex_special_chars['Ì'] = '{\`I}';
430  $bibtex_special_chars['Ò'] = '{\`O}';
431  $bibtex_special_chars['Ù'] = '{\`U}';
432 
433  $bibtex_special_chars['á'] = '{\\\'a}';
434  $bibtex_special_chars['é'] = '{\\\'e}';
435  $bibtex_special_chars['í'] = '{\\\'i}';
436  $bibtex_special_chars['ó'] = '{\\\'o}';
437  $bibtex_special_chars['ú'] = '{\\\'u}';
438 
439  $bibtex_special_chars['Á'] = '{\\\'A}';
440  $bibtex_special_chars['É'] = '{\\\'E}';
441  $bibtex_special_chars['Í'] = '{\\\'I}';
442  $bibtex_special_chars['Ó'] = '{\\\'O}';
443  $bibtex_special_chars['Ú'] = '{\\\'U}';
444 
445  $bibtex_special_chars['à'] = '{\`a}';
446  $bibtex_special_chars['è'] = '{\`e}';
447  $bibtex_special_chars['ì'] = '{\`i}';
448  $bibtex_special_chars['ò'] = '{\`o}';
449  $bibtex_special_chars['ù'] = '{\`u}';
450 
451  $bibtex_special_chars['À'] = '{\`A}';
452  $bibtex_special_chars['È'] = '{\`E}';
453  $bibtex_special_chars['Ì'] = '{\`I}';
454  $bibtex_special_chars['Ò'] = '{\`O}';
455  $bibtex_special_chars['Ù'] = '{\`U}';
456 
457  $bibtex_special_chars['ç'] = '{\c c}';
458  $bibtex_special_chars['ß'] = '{\ss}';
459  $bibtex_special_chars['ñ'] = '{\~n}';
460  $bibtex_special_chars['Ñ'] = '{\~N}';
461 
462  return str_replace($bibtex_special_chars, array_keys($bibtex_special_chars), $file_content);
463  }
464 
465 
476  public function doCloneObject(ilObjBibliographic $new_obj, $a_target_id, $a_copy_id = 0) {
477  $new_obj->cloneStructure($this->getId());
478 
479  return $new_obj;
480  }
481 
482 
490  public function cloneStructure($original_id) {
491  $original = new ilObjBibliographic($original_id);
492 
493  $this->moveFile($original->getFileAbsolutePath());
494 
495  $this->setOnline($original->getOnline());
496  $this->setDescription($original->getDescription());
497  $this->setTitle($original->getTitle());
498  $this->setType($original->getType());
499 
500  $this->doUpdate();
501  }
502 
503 
504  protected static function __removeSpacesAndDashesAtBeginning($input) {
505  for ($i = 0; $i < strlen($input); $i ++) {
506  if ($input[$i] != " " && $input[$i] != "-") {
507  return substr($input, $i);
508  }
509  }
510  }
511 
512 
518  public function writeSourcefileEntriesToDb() {
519 
520  //Read File
521  switch ($this->getFiletype()) {
522  case("ris"):
523  $entries_from_file = self::__readRisFile($this->getFileAbsolutePath());
524  break;
525  case("bib"):
526  $entries_from_file = self::__readBibFile($this->getFileAbsolutePath());
527  break;
528  }
529 
530  //fill each entry into a ilBibliographicEntry object and then write it to DB by executing doCreate()
531  foreach ($entries_from_file as $file_entry) {
532  $type = NULL;
533  $x = 0;
534  $parsed_entry = array();
535 
536  foreach ($file_entry as $key => $attribute) {
537  // if the attribute is an array, make a comma separated string out of it
538  if (is_array($attribute)) {
539  $attribute = implode(", ", $attribute);
540  }
541 
542  if(mb_strlen($attribute, 'UTF-8') > self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH){
543  $attribute = mb_substr($attribute, 0, self::ATTRIBUTE_VALUE_MAXIMAL_TEXT_LENGTH - 3, 'UTF-8') . '...';
544  }
545 
546  // ty (RIS) or entryType (BIB) is the type and is treated seperately
547  if (strtolower($key) == 'ty' || strtolower($key) == 'entrytype') {
548  $type = $attribute;
549  continue;
550  }
551 
552  //TODO - Refactoring for ILIAS 4.5 - get rid off array restructuring
553  //change array structure (name not as the key, but under the key "name")
554  $parsed_entry[$x]['name'] = $key;
555  $parsed_entry[$x ++]['value'] = $attribute;
556  }
557  //create the entry and fill data into database by executing doCreate()
558  $entry_model = new ilBibliographicEntry($this->getFiletype());
559  $entry_model->setType($type);
560  $entry_model->setAttributes($parsed_entry);
561  $entry_model->setBibliographicObjId($this->getId());
562  $entry_model->doCreate();
563  }
564  }
565 
566 
574  function setOnline($a_online) {
575  $this->is_online = $a_online;
576  }
577 
578 
584  function getOnline() {
585  return $this->is_online;
586  }
587 }