ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilFileDataMail.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 
12 require_once("./Services/FileSystem/classes/class.ilFileData.php");
13 
15 {
21  var $user_id;
22 
29 
31 
39  public function __construct($a_user_id = 0)
40  {
41  define('MAILPATH','mail');
43  $this->mail_path = parent::getPath()."/".MAILPATH;
44  $this->checkReadWrite();
45  $this->user_id = $a_user_id;
46 
47 
48  $this->__initAttachmentMaxSize();
49  }
50 
57  function initDirectory()
58  {
59  if(is_writable($this->getPath()))
60  {
61  if(mkdir($this->getPath().'/'.MAILPATH))
62  {
63  if(chmod($this->getPath().'/'.MAILPATH,0755))
64  {
65  $this->mail_path = $this->getPath().'/'.MAILPATH;
66  return true;
67  }
68  }
69  }
70  return false;
71  }
72  function getUploadLimit()
73  {
75  }
76 
82  function getMailPath()
83  {
84  return $this->mail_path;
85  }
86 
94  public function getAttachmentPathByMD5Filename($a_filename,$a_mail_id)
95  {
96  global $ilDB;
97 
98 /* $query = "SELECT path FROM mail_attachment ".
99  "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
100 
101  $row = $this->ilias->db->getRow($query,DB_FETCHMODE_OBJECT);
102  $path = $this->getMailPath().'/'.$row->path;
103 */
104  $query = $ilDB->query("SELECT path FROM mail_attachment
105  WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer')."");
106 
107  $rel_path = "";
108  while($row = $ilDB->fetchObject($query))
109  {
110  $rel_path = $row->path;
111  $path = $this->getMailPath().'/'.$row->path;
112 
113  }
114 
115  $files = ilUtil::getDir($path);
116  foreach((array)$files as $file)
117  {
118  if($file['type'] == 'file' && md5($file['entry']) == $a_filename)
119  {
120  return array(
121  'path' => $this->getMailPath().'/'.$rel_path.'/'.$file['entry'],
122  'filename' => $file['entry']
123  );
124  }
125  }
126  return '';
127  }
128 
129 
137  function getAttachmentPath($a_filename,$a_mail_id)
138  {
139  global $ilDB;
140 
141 /* $query = "SELECT path FROM mail_attachment ".
142  "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
143 
144  $row = $this->ilias->db->getRow($query,DB_FETCHMODE_OBJECT);
145  $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
146 */
147  $query = $ilDB->query("SELECT path FROM mail_attachment ".
148  "WHERE mail_id = ".$ilDB->quote($a_mail_id, 'integer')."");
149 
150  while($row = $ilDB->fetchObject($query))
151  {
152  $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
153  }
154 
155  if(file_exists($path))
156  {
157  if(is_readable($path))
158  {
159  return $path;
160  }
161  return '';
162  }
163  return '';
164  }
172  function adoptAttachments($a_attachments,$a_mail_id)
173  {
174  if(is_array($a_attachments))
175  {
176  foreach($a_attachments as $file)
177  {
178  $path = $this->getAttachmentPath($file,$a_mail_id);
179  if(!copy($path,$this->getMailPath().'/'.$this->user_id.'_'.$file))
180  {
181  return "ERROR: $this->getMailPath().'/'.$this->user_id.'_'.$file cannot be created";
182  }
183  }
184  }
185  else
186  {
187  return "ARRAY REQUIRED";
188  }
189  return '';
190  }
191 
198  function checkReadWrite()
199  {
200  if(is_writable($this->mail_path) && is_readable($this->mail_path))
201  {
202  return true;
203  }
204  else
205  {
206  $this->ilias->raiseError("Mail directory is not readable/writable by webserver: ".$this->mail_path,$this->ilias->error_obj->FATAL);
207  }
208  }
214  function getUserFilesData()
215  {
216  return $files = $this->getUnsentFiles();
217  }
218 
225  function getUnsentFiles()
226  {
227  $files = array();
228  $dp = opendir($this->mail_path);
229 
230  while($file = readdir($dp))
231  {
232  if(is_dir($file))
233  {
234  continue;
235  }
236  list($uid,$rest) = explode('_',$file,2);
237  if($uid == $this->user_id)
238  {
239  if(!is_dir($this->mail_path.'/'.$file))
240  {
241  $files[] = array(
242  'name' => $rest,
243  'size' => filesize($this->mail_path.'/'.$file),
244  'ctime' => filectime($this->mail_path.'/'.$file)
245  );
246  }
247  }
248  }
249  closedir($dp);
250  return $files;
251  }
252 
259  public function storeAsAttachment($a_filename,$a_content)
260  {
261  if(strlen($a_content) >= $this->mail_maxsize_attach)
262  {
263  return 1;
264  }
265  $name = ilUtil::_sanitizeFilemame($a_filename);
266  $this->rotateFiles($this->getMailPath().'/'.$this->user_id.'_'.$name);
267 
268  $abs_path = $this->getMailPath().'/'.$this->user_id.'_'.$name;
269 
270  if(!$fp = @fopen($abs_path,'w+'))
271  {
272  return false;
273  }
274  if(@fwrite($fp,$a_content) === false)
275  {
276  @fclose($fp);
277  return false;
278  }
279  @fclose($fp);
280  return true;
281  }
282 
283 
290  function storeUploadedFile($a_http_post_file)
291  {
292  if($a_http_post_file["size"] >= $this->mail_maxsize_attach)
293  {
294  return 1;
295  }
296 
297  if(isset($a_http_post_file) && $a_http_post_file['size'])
298  {
299  $a_http_post_file['name'] = ilUtil::_sanitizeFilemame($a_http_post_file['name']);
300 
301  $this->rotateFiles($this->getMailPath().'/'.$this->user_id.'_'.$a_http_post_file['name']);
302 
304  $a_http_post_file['tmp_name'],
305  $a_http_post_file['name'],
306  $this->getMailPath().'/'.$this->user_id.'_'.$a_http_post_file['name']
307  );
308 
309  return 0;
310  }
311  return 1;
312  }
313 
320  function copyAttachmentFile($a_abs_path,$a_new_name)
321  {
322  @copy($a_abs_path,$this->getMailPath()."/".$this->user_id."_".$a_new_name);
323 
324  return true;
325  }
326 
327 
328 
336  function rotateFiles($a_path)
337  {
338  if(file_exists($a_path))
339  {
340  $this->rotateFiles($a_path.".old");
341  return rename($a_path,$a_path.'.old');
342  }
343  return true;
344  }
351  function unlinkFiles($a_filenames)
352  {
353  if(is_array($a_filenames))
354  {
355  foreach($a_filenames as $file)
356  {
357  if(!$this->unlinkFile($file))
358  {
359  return $file;
360  }
361  }
362  }
363  return '';
364  }
371  function unlinkFile($a_filename)
372  {
373  if(file_exists($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename)))
374  {
375  return unlink($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename));
376  }
377  }
384  function getAbsolutePath($a_path)
385  {
386  return $this->mail_path.'/'.$this->user_id.'_'.$a_path;
387  }
388 
396  function saveFiles($a_mail_id,$a_attachments)
397  {
398  if(!$a_mail_id)
399  {
400  return "INTERNAL HERE ERROR: No valid mail_id given";
401  }
402  if(is_array($a_attachments))
403  {
404  foreach($a_attachments as $attachment)
405  {
406  if(!$this->saveFile($a_mail_id,$attachment))
407  {
408  return $attachment;
409  }
410  }
411  }
412  else
413  {
414  return "ARRAY REQUIRED";
415  }
416  return '';
417  }
418 
419  public static function getStorage($a_mail_id, $a_usr_id)
420  {
421  static $fsstorage_cache = array();
422 
423  if(!is_object($fsstorage_cache[$a_mail_id][$a_usr_id]))
424  {
425  include_once 'Services/Mail/classes/class.ilFSStorageMail.php';
426  $fsstorage_cache[$a_mail_id][$a_usr_id] = new ilFSStorageMail($a_mail_id, $a_usr_id);
427  }
428 
429  return $fsstorage_cache[$a_mail_id][$a_usr_id];
430  }
431 
439  function saveFile($a_mail_id,$a_attachment)
440  {
441  $oStorage = self::getStorage($a_mail_id, $this->user_id);
442  $oStorage->create();
443  $storage_directory = $oStorage->getAbsolutePath();
444 
445  if(@!is_dir($storage_directory))
446  {
447  return false;
448  }
449 
450  return copy($this->mail_path.'/'.$this->user_id.'_'.$a_attachment,
451  $storage_directory.'/'.$a_attachment);
452  }
459  function checkFilesExist($a_files)
460  {
461  if($a_files)
462  {
463  foreach($a_files as $file)
464  {
465  if(!file_exists($this->mail_path.'/'.$this->user_id.'_'.$file))
466  {
467  return false;
468  }
469  }
470  return true;
471  }
472  return true;
473  }
481  function assignAttachmentsToDirectory($a_mail_id,$a_sent_mail_id)
482  {
483  global $ilDB;
484 
485 /* $query = "INSERT INTO mail_attachment ".
486  "SET mail_id = ".$ilDB->quote($a_mail_id).", ".
487  "path = ".$ilDB->quote($this->user_id."_".$a_sent_mail_id)." ";
488  $res = $this->ilias->db->query($query);
489 */
490 
491  $oStorage = self::getStorage($a_sent_mail_id, $this->user_id);
492  $res = $ilDB->manipulateF('
493  INSERT INTO mail_attachment
494  ( mail_id, path) VALUES (%s, %s)',
495  array('integer', 'text'),
496  array($a_mail_id, $oStorage->getRelativePathExMailDirectory())
497  );
498 
499  }
506  function deassignAttachmentFromDirectory($a_mail_id)
507  {
508  global $ilDB;
509  // IF IT'S THE LAST MAIL CONTAINING THESE ATTACHMENTS => DELETE ATTACHMENTS
510  $res = $ilDB->query("SELECT path FROM mail_attachment
511  WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer'));
512 
513  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
514  {
515  $path = $row->path;
516  }
517  if($path)
518  {
519  $res = $ilDB->query("SELECT COUNT(mail_id) count_mail_id FROM mail_attachment
520  WHERE path = ".$ilDB->quote($path,'text')) ;
521 
522  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
523  {
524  $cnt_mail_id = $row->count_mail_id;
525  }
526  if($cnt_mail_id == 1)
527  {
529  }
530  }
531 
532  $res = $ilDB->manipulateF("DELETE FROM mail_attachment
533  WHERE mail_id = %s",
534  array('integer'),
535  array($a_mail_id));
536  return true;
537  }
538 
539  function __deleteAttachmentDirectory($a_rel_path)
540  {
541  ilUtil::delDir($this->mail_path."/".$a_rel_path);
542 
543  return true;
544  }
546  {
549  // Copy of ilFileInputGUI: begin
550  // get the value for the maximal uploadable filesize from the php.ini (if available)
551  $umf = ini_get("upload_max_filesize");
552  // get the value for the maximal post data from the php.ini (if available)
553  $pms = ini_get("post_max_size");
554 
555  //convert from short-string representation to "real" bytes
556  $multiplier_a=array("K"=>1024, "M"=>1024*1024, "G"=>1024*1024*1024);
557 
558  $umf_parts=preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
559  $pms_parts=preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY);
560 
561  if (count($umf_parts) == 2) { $umf = $umf_parts[0]*$multiplier_a[$umf_parts[1]]; }
562  if (count($pms_parts) == 2) { $pms = $pms_parts[0]*$multiplier_a[$pms_parts[1]]; }
563 
564  // use the smaller one as limit
565  $max_filesize = min($umf, $pms);
566 
567  if (!$max_filesize) $max_filesize = max($umf, $pms);
568  // Copy of ilFileInputGUI: end
569 
570  $mail_system_limitation_in_byte = (float)$this->ilias->getSetting('mail_maxsize_attach', 0) * 1024;
571  if(!$mail_system_limitation_in_byte)
572  {
573  $mail_system_limitation_in_byte = $max_filesize;
574  }
575 
576  $mail_system_limitation_in_byte = min($mail_system_limitation_in_byte, $max_filesize);
577 
578  $this->mail_maxsize_attach = $mail_system_limitation_in_byte;
579  }
580 
590  {
591  // XXX - This method is extremely slow. We should
592  // use a cache to speed it up, for example, we should
593  // store the disk space used in table mail_attachment.
594  global $ilDB, $lng;
595 
596  $mail_data_dir = ilUtil::getDataDir('filesystem').DIRECTORY_SEPARATOR."mail";
597 
598  $q = "SELECT path ".
599  "FROM mail_attachment ma ".
600  "JOIN mail m ON ma.mail_id=m.mail_id ".
601  "WHERE m.user_id = ".$ilDB->quote($user_id);
602  $result_set = $ilDB->query($q);
603  $size = 0;
604  $count = 0;
605  while($row = $result_set->fetchRow(DB_FETCHMODE_ASSOC))
606  {
607  $attachment_path = $mail_data_dir.DIRECTORY_SEPARATOR.$row['path'];
608  $attachment_size = ilUtil::dirsize($attachment_path);
609  if ($attachment_size != -1)
610  {
611  $size += $attachment_size;
612  }
613  $count++;
614  }
615  return array('count'=>$count, 'size'=>$size);
616  }
617 
621  public function onUserDelete()
622  {
626  global $ilDB;
627 
628  // Delete uploaded mail files which are not attached to any message
629  try
630  {
631  $iter = new RegexIterator(
632  new DirectoryIterator($this->getMailPath()), '/^'.$this->user_id.'_/'
633  );
634  foreach($iter as $file)
635  {
640  if($file->isFile())
641  {
642  @unlink($file->getPathname());
643  }
644  }
645  }
646  catch(Exception $e) { }
647 
648  // Select all files attached to messages which are not shared (... = 1) with other messages anymore
649  $query = '
650  SELECT DISTINCT(ma1.path)
651  FROM mail_attachment ma1
652  INNER JOIN mail
653  ON mail.mail_id = ma1.mail_id
654  WHERE mail.user_id = %s
655  AND (SELECT COUNT(tmp.path) FROM mail_attachment tmp WHERE tmp.path = ma1.path) = 1
656  ';
657  $res = $ilDB->queryF(
658  $query,
659  array('integer'),
660  array($this->user_id)
661  );
662  while($row = $ilDB->fetchAssoc($res))
663  {
664  try
665  {
666  $path = $this->getMailPath().DIRECTORY_SEPARATOR.$row['path'];
667  $iter = new RecursiveIteratorIterator(
668  new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
669  );
670  foreach($iter as $file)
671  {
676  if($file->isDir())
677  {
678  @rmdir($file->getPathname());
679  }
680  else
681  {
682  @unlink($file->getPathname());
683  }
684  }
685  @rmdir($path);
686  }
687  catch(Exception $e) { }
688  }
689 
690  // Delete each mail attachment row assigned to a message of the deleted user.
691  if($ilDB->getDBType() == 'mysql' || $ilDB->getDBType() == 'innodb')
692  {
693  $ilDB->manipulateF('
694  DELETE m1
695  FROM mail_attachment m1
696  INNER JOIN (
697  SELECT mail_attachment.mail_id
698  FROM mail
699  INNER JOIN mail_attachment
700  ON mail_attachment.mail_id = mail.mail_id
701  WHERE user_id = %s
702  ) m2
703  ON m2.mail_id = m1.mail_id
704  ',
705  array('integer'),
706  array($this->user_id)
707  );
708  }
709  else
710  {
711  // Oracle and Postgres
712  $ilDB->manipulateF('
713  DELETE FROM mail_attachment
714  WHERE mail_attachment.mail_id IN (
715  SELECT mail_attachment.mail_id
716  FROM mail
717  INNER JOIN mail_attachment
718  ON mail_attachment.mail_id = mail.mail_id
719  WHERE user_id = %s
720  )
721  ',
722  array('integer'),
723  array($this->user_id)
724  );
725  }
726  }
727 }
728 ?>