ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
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 require_once("./Services/Utilities/classes/class.ilFileUtils.php");
14 
19 {
25  var $user_id;
26 
33 
38 
46  public function __construct($a_user_id = 0)
47  {
48  define('MAILPATH','mail');
49  parent::__construct();
50  $this->mail_path = parent::getPath()."/".MAILPATH;
51  $this->checkReadWrite();
52  $this->user_id = $a_user_id;
53 
55  }
56 
63  function initDirectory()
64  {
65  if(is_writable($this->getPath()))
66  {
67  if(mkdir($this->getPath().'/'.MAILPATH))
68  {
69  if(chmod($this->getPath().'/'.MAILPATH,0755))
70  {
71  $this->mail_path = $this->getPath().'/'.MAILPATH;
72  return true;
73  }
74  }
75  }
76  return false;
77  }
78 
82  public function getUploadLimit()
83  {
85  }
86 
90  public function getAttachmentsTotalSizeLimit()
91  {
92  $max_size = $this->ilias->getSetting('mail_maxsize_attach', '');
93  if(!strlen($max_size))
94  {
95  return null;
96  }
97 
98  return (float)$this->ilias->getSetting('mail_maxsize_attach', 0) * 1024;
99  }
100 
106  function getMailPath()
107  {
108  return $this->mail_path;
109  }
110 
115  {
116  return $this->mail_path . '/' . $this->user_id . '_';
117  }
118 
126  public function getAttachmentPathByMD5Filename($a_filename,$a_mail_id)
127  {
128  global $ilDB;
129 
130 /* $query = "SELECT path FROM mail_attachment ".
131  "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
132 
133  $row = $this->ilias->db->getRow($query,ilDBConstants::FETCHMODE_OBJECT);
134  $path = $this->getMailPath().'/'.$row->path;
135 */
136  $query = $ilDB->query("SELECT path FROM mail_attachment
137  WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer')."");
138 
139  $rel_path = "";
140  while($row = $ilDB->fetchObject($query))
141  {
142  $rel_path = $row->path;
143  $path = $this->getMailPath().'/'.$row->path;
144 
145  }
146 
148  foreach((array)$files as $file)
149  {
150  if($file['type'] == 'file' && md5($file['entry']) == $a_filename)
151  {
152  return array(
153  'path' => $this->getMailPath().'/'.$rel_path.'/'.$file['entry'],
154  'filename' => $file['entry']
155  );
156  }
157  }
158  return '';
159  }
160 
161 
169  function getAttachmentPath($a_filename,$a_mail_id)
170  {
171  global $ilDB;
172 
173 /* $query = "SELECT path FROM mail_attachment ".
174  "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
175 
176  $row = $this->ilias->db->getRow($query,ilDBConstants::FETCHMODE_OBJECT);
177  $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
178 */
179  $query = $ilDB->query("SELECT path FROM mail_attachment ".
180  "WHERE mail_id = ".$ilDB->quote($a_mail_id, 'integer')."");
181 
182  while($row = $ilDB->fetchObject($query))
183  {
184  $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
185  }
186 
187  if(file_exists($path))
188  {
189  if(is_readable($path))
190  {
191  return $path;
192  }
193  return '';
194  }
195  return '';
196  }
204  function adoptAttachments($a_attachments,$a_mail_id)
205  {
206  if(is_array($a_attachments))
207  {
208  foreach($a_attachments as $file)
209  {
210  $path = $this->getAttachmentPath($file,$a_mail_id);
211  if(!copy($path,$this->getMailPath().'/'.$this->user_id.'_'.$file))
212  {
213  return "ERROR: $this->getMailPath().'/'.$this->user_id.'_'.$file cannot be created";
214  }
215  }
216  }
217  else
218  {
219  return "ARRAY REQUIRED";
220  }
221  return '';
222  }
223 
230  function checkReadWrite()
231  {
232  if(is_writable($this->mail_path) && is_readable($this->mail_path))
233  {
234  return true;
235  }
236  else
237  {
238  $this->ilias->raiseError("Mail directory is not readable/writable by webserver: ".$this->mail_path,$this->ilias->error_obj->FATAL);
239  }
240  }
246  function getUserFilesData()
247  {
248  return $this->getUnsentFiles();
249  }
250 
257  private function getUnsentFiles()
258  {
259  $files = array();
260 
261  $iter = new DirectoryIterator($this->mail_path);
262  foreach($iter as $file)
263  {
267  if($file->isFile())
268  {
269  list($uid, $rest) = explode('_', $file->getFilename(), 2);
270  if($uid == $this->user_id)
271  {
272  $files[] = array(
273  'name' => $rest,
274  'size' => $file->getSize(),
275  'ctime' => $file->getCTime()
276  );
277  }
278  }
279  }
280 
281  return $files;
282  }
283 
290  public function storeAsAttachment($a_filename,$a_content)
291  {
292  if(strlen($a_content) >= $this->getUploadLimit())
293  {
294  return 1;
295  }
296 
297  $name = ilUtil::_sanitizeFilemame($a_filename);
298  $this->rotateFiles($this->getMailPath().'/'.$this->user_id.'_'.$name);
299 
300  $abs_path = $this->getMailPath().'/'.$this->user_id.'_'.$name;
301 
302  if(!$fp = @fopen($abs_path,'w+'))
303  {
304  return false;
305  }
306  if(@fwrite($fp,$a_content) === false)
307  {
308  @fclose($fp);
309  return false;
310  }
311  @fclose($fp);
312  return true;
313  }
314 
318  public function storeUploadedFile($file)
319  {
320  $file['name'] = ilUtil::_sanitizeFilemame($file['name']);
321 
322  $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $file['name']);
323 
325  $file['tmp_name'],
326  $file['name'],
327  $this->getMailPath() . '/' . $this->user_id . '_' . $file['name']
328  );
329  }
330 
337  function copyAttachmentFile($a_abs_path,$a_new_name)
338  {
339  @copy($a_abs_path,$this->getMailPath()."/".$this->user_id."_".$a_new_name);
340 
341  return true;
342  }
343 
344 
345 
353  function rotateFiles($a_path)
354  {
355  if(file_exists($a_path))
356  {
357  $this->rotateFiles($a_path.".old");
358  return \ilFileUtils::rename($a_path, $a_path . '.old');
359  }
360  return true;
361  }
368  function unlinkFiles($a_filenames)
369  {
370  if(is_array($a_filenames))
371  {
372  foreach($a_filenames as $file)
373  {
374  if(!$this->unlinkFile($file))
375  {
376  return $file;
377  }
378  }
379  }
380  return '';
381  }
388  function unlinkFile($a_filename)
389  {
390  if(file_exists($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename)))
391  {
392  return unlink($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename));
393  }
394  }
401  function getAbsolutePath($fileName)
402  {
403  return $this->getAbsoluteAttachmentPoolPathPrefix() . $fileName;
404  }
405 
411  public function saveFiles($a_mail_id, array $a_attachments)
412  {
413  if(!is_numeric($a_mail_id) || $a_mail_id < 1)
414  {
415  throw new InvalidArgumentException('The passed mail_id must be a valid integer!');
416  }
417 
418  foreach($a_attachments as $attachment)
419  {
420  $this->saveFile($a_mail_id, $attachment);
421  }
422  }
423 
424  public static function getStorage($a_mail_id, $a_usr_id)
425  {
426  static $fsstorage_cache = array();
427 
428  if(!is_object($fsstorage_cache[$a_mail_id][$a_usr_id]))
429  {
430  include_once 'Services/Mail/classes/class.ilFSStorageMail.php';
431  $fsstorage_cache[$a_mail_id][$a_usr_id] = new ilFSStorageMail($a_mail_id, $a_usr_id);
432  }
433 
434  return $fsstorage_cache[$a_mail_id][$a_usr_id];
435  }
436 
444  function saveFile($a_mail_id,$a_attachment)
445  {
446  $oStorage = self::getStorage($a_mail_id, $this->user_id);
447  $oStorage->create();
448  $storage_directory = $oStorage->getAbsolutePath();
449 
450  if(@!is_dir($storage_directory))
451  {
452  return false;
453  }
454 
455  return copy($this->mail_path.'/'.$this->user_id.'_'.$a_attachment,
456  $storage_directory.'/'.$a_attachment);
457  }
464  function checkFilesExist($a_files)
465  {
466  if($a_files)
467  {
468  foreach($a_files as $file)
469  {
470  if(!file_exists($this->mail_path.'/'.$this->user_id.'_'.$file))
471  {
472  return false;
473  }
474  }
475  return true;
476  }
477  return true;
478  }
486  function assignAttachmentsToDirectory($a_mail_id,$a_sent_mail_id)
487  {
488  global $ilDB;
489 
490 /* $query = "INSERT INTO mail_attachment ".
491  "SET mail_id = ".$ilDB->quote($a_mail_id).", ".
492  "path = ".$ilDB->quote($this->user_id."_".$a_sent_mail_id)." ";
493  $res = $this->ilias->db->query($query);
494 */
495 
496  $oStorage = self::getStorage($a_sent_mail_id, $this->user_id);
497  $res = $ilDB->manipulateF('
498  INSERT INTO mail_attachment
499  ( mail_id, path) VALUES (%s, %s)',
500  array('integer', 'text'),
501  array($a_mail_id, $oStorage->getRelativePathExMailDirectory())
502  );
503 
504  }
511  function deassignAttachmentFromDirectory($a_mail_id)
512  {
513  global $ilDB;
514  // IF IT'S THE LAST MAIL CONTAINING THESE ATTACHMENTS => DELETE ATTACHMENTS
515  $res = $ilDB->query("SELECT path FROM mail_attachment
516  WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer'));
517 
518  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
519  {
520  $path = $row->path;
521  }
522  if($path)
523  {
524  $res = $ilDB->query("SELECT COUNT(mail_id) count_mail_id FROM mail_attachment
525  WHERE path = ".$ilDB->quote($path,'text')) ;
526 
527  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
528  {
529  $cnt_mail_id = $row->count_mail_id;
530  }
531  if($cnt_mail_id == 1)
532  {
534  }
535  }
536 
537  $res = $ilDB->manipulateF("DELETE FROM mail_attachment
538  WHERE mail_id = %s",
539  array('integer'),
540  array($a_mail_id));
541  return true;
542  }
543 
544  function __deleteAttachmentDirectory($a_rel_path)
545  {
546  ilUtil::delDir($this->mail_path."/".$a_rel_path);
547 
548  return true;
549  }
550 
554  protected function initAttachmentMaxUploadSize()
555  {
558  // Copy of ilFileInputGUI: begin
559  // get the value for the maximal uploadable filesize from the php.ini (if available)
560  $umf = ini_get("upload_max_filesize");
561  // get the value for the maximal post data from the php.ini (if available)
562  $pms = ini_get("post_max_size");
563 
564  //convert from short-string representation to "real" bytes
565  $multiplier_a = array("K" => 1024, "M" => 1024 * 1024, "G" => 1024 * 1024 * 1024);
566 
567  $umf_parts = preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
568  $pms_parts = preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
569 
570  if(count($umf_parts) == 2)
571  {
572  $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
573  }
574  if(count($pms_parts) == 2)
575  {
576  $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
577  }
578 
579  // use the smaller one as limit
580  $max_filesize = min($umf, $pms);
581 
582  if(!$max_filesize) $max_filesize = max($umf, $pms);
583  // Copy of ilFileInputGUI: end
584 
585  $this->mail_max_upload_file_size = $max_filesize;
586  }
587 
596  public static function _lookupDiskUsageOfUser($user_id)
597  {
598  // XXX - This method is extremely slow. We should
599  // use a cache to speed it up, for example, we should
600  // store the disk space used in table mail_attachment.
601  global $ilDB, $lng;
602 
603  $mail_data_dir = ilUtil::getDataDir('filesystem').DIRECTORY_SEPARATOR."mail";
604 
605  $q = "SELECT path ".
606  "FROM mail_attachment ma ".
607  "JOIN mail m ON ma.mail_id=m.mail_id ".
608  "WHERE m.user_id = ".$ilDB->quote($user_id);
609  $result_set = $ilDB->query($q);
610  $size = 0;
611  $count = 0;
612  while($row = $result_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC))
613  {
614  $attachment_path = $mail_data_dir.DIRECTORY_SEPARATOR.$row['path'];
615  $attachment_size = ilUtil::dirsize($attachment_path);
616  if ($attachment_size != -1)
617  {
618  $size += $attachment_size;
619  }
620  $count++;
621  }
622  return array('count'=>$count, 'size'=>$size);
623  }
624 
628  public function onUserDelete()
629  {
633  global $ilDB;
634 
635  // Delete uploaded mail files which are not attached to any message
636  try
637  {
638  $iter = new RegexIterator(
639  new DirectoryIterator($this->getMailPath()), '/^'.$this->user_id.'_/'
640  );
641  foreach($iter as $file)
642  {
647  if($file->isFile())
648  {
649  @unlink($file->getPathname());
650  }
651  }
652  }
653  catch(Exception $e) { }
654 
655  // Select all files attached to messages which are not shared (... = 1) with other messages anymore
656  $query = '
657  SELECT DISTINCT(ma1.path)
658  FROM mail_attachment ma1
659  INNER JOIN mail
660  ON mail.mail_id = ma1.mail_id
661  WHERE mail.user_id = %s
662  AND (SELECT COUNT(tmp.path) FROM mail_attachment tmp WHERE tmp.path = ma1.path) = 1
663  ';
664  $res = $ilDB->queryF(
665  $query,
666  array('integer'),
667  array($this->user_id)
668  );
669  while($row = $ilDB->fetchAssoc($res))
670  {
671  try
672  {
673  $path = $this->getMailPath().DIRECTORY_SEPARATOR.$row['path'];
674  $iter = new RecursiveIteratorIterator(
675  new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
676  );
677  foreach($iter as $file)
678  {
683  if($file->isDir())
684  {
685  @rmdir($file->getPathname());
686  }
687  else
688  {
689  @unlink($file->getPathname());
690  }
691  }
692  @rmdir($path);
693  }
694  catch(Exception $e) { }
695  }
696 
697  // Delete each mail attachment rows assigned to a message of the deleted user.
698  $ilDB->manipulateF('
699  DELETE
700  FROM mail_attachment
701  WHERE EXISTS(
702  SELECT mail.mail_id
703  FROM mail
704  WHERE mail.user_id = %s AND mail.mail_id = mail_attachment.mail_id
705  )
706  ',
707  array('integer'),
708  array($this->user_id)
709  );
710  }
711 }
712 ?>
$files
Definition: add-vimline.php:18
checkReadWrite()
check if directory is writable overwritten method from base class private
getAttachmentPath($a_filename, $a_mail_id)
get the path of a specific attachment
$rest
Definition: goto.php:48
$size
Definition: RandomTest.php:79
unlinkFile($a_filename)
unlink one uploaded file expects a filename e.g &#39;foo&#39;
__construct($a_user_id=0)
Constructor call base constructors checks if directory is writable and sets the optional user_id...
getMailPath()
get mail path public
This class handles all operations on files (attachments) in directory ilias_data/mail.
getAttachmentPathByMD5Filename($a_filename, $a_mail_id)
get the path of a specific attachment
getPath()
get Path public
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
saveFile($a_mail_id, $a_attachment)
save attachment file in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<user_id>...
unlinkFiles($a_filenames)
unlink files: expects an array of filenames e.g.
adoptAttachments($a_attachments, $a_mail_id)
adopt attachments (in case of forwarding a mail)
storeAsAttachment($a_filename, $a_content)
Store content as attachment.
checkFilesExist($a_files)
check if files exist
initDirectory()
init directory overwritten method public
static _sanitizeFilemame($a_filename)
getUserFilesData()
get all attachments of a specific user public
$a_content
Definition: workflow.php:94
This class handles all operations on files in directory /ilias_data/.
assignAttachmentsToDirectory($a_mail_id, $a_sent_mail_id)
assign attachments to mail directory
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
redirection script todo: (a better solution should control the processing via a xml file) ...
Create styles array
The data for the language used.
static _lookupDiskUsageOfUser($user_id)
Returns the number of bytes used on the harddisk for mail attachments, by the user with the specified...
static dirsize($directory)
get size of a directory or a file.
saveFiles($a_mail_id, array $a_attachments)
Saves all attachment files in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<us...
copyAttachmentFile($a_abs_path, $a_new_name)
Copy files in mail directory.
static getDataDir()
get data directory (outside webspace)
getAbsolutePath($fileName)
get absolute path of filename
global $lng
Definition: privfeed.php:17
global $ilDB
deassignAttachmentFromDirectory($a_mail_id)
dassign attachments from mail directory
if(!file_exists("$old.txt")) if($old===$new) if(file_exists("$new.txt")) $file
__deleteAttachmentDirectory($a_rel_path)
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static getStorage($a_mail_id, $a_usr_id)
rotateFiles($a_path)
rotate files with same name recursive method