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
12require_once("./Services/FileSystem/classes/class.ilFileData.php");
13require_once("./Services/Utilities/classes/class.ilFileUtils.php");
14
19{
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
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 }
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 }
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?>
$size
Definition: RandomTest.php:79
$files
Definition: add-vimline.php:18
An exception for terminatinating execution or to throw for unit testing.
This class handles all operations on files (attachments) in directory ilias_data/mail.
copyAttachmentFile($a_abs_path, $a_new_name)
Copy files in mail directory.
checkReadWrite()
check if directory is writable overwritten method from base class @access private
saveFile($a_mail_id, $a_attachment)
save attachment file in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<user_id>...
getAbsolutePath($fileName)
get absolute path of filename
getAttachmentPath($a_filename, $a_mail_id)
get the path of a specific attachment
unlinkFiles($a_filenames)
unlink files: expects an array of filenames e.g.
assignAttachmentsToDirectory($a_mail_id, $a_sent_mail_id)
assign attachments to mail directory
static getStorage($a_mail_id, $a_usr_id)
static _lookupDiskUsageOfUser($user_id)
Returns the number of bytes used on the harddisk for mail attachments, by the user with the specified...
initDirectory()
init directory overwritten method @access public
adoptAttachments($a_attachments, $a_mail_id)
adopt attachments (in case of forwarding a mail)
unlinkFile($a_filename)
unlink one uploaded file expects a filename e.g 'foo'
__construct($a_user_id=0)
Constructor call base constructors checks if directory is writable and sets the optional user_id.
getAttachmentPathByMD5Filename($a_filename, $a_mail_id)
get the path of a specific attachment
storeAsAttachment($a_filename, $a_content)
Store content as attachment.
rotateFiles($a_path)
rotate files with same name recursive method
getMailPath()
get mail path @access public
getUserFilesData()
get all attachments of a specific user @access public
checkFilesExist($a_files)
check if files exist
deassignAttachmentFromDirectory($a_mail_id)
dassign attachments from mail directory
saveFiles($a_mail_id, array $a_attachments)
Saves all attachment files in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<us...
__deleteAttachmentDirectory($a_rel_path)
This class handles all operations on files in directory /ilias_data/.
getPath()
get Path @access public
static getDataDir()
get data directory (outside webspace)
static moveUploadedFile($a_file, $a_name, $a_target, $a_raise_errors=true, $a_mode="move_uploaded")
move uploaded file
static delDir($a_dir, $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
static _sanitizeFilemame($a_filename)
static getDir($a_dir, $a_rec=false, $a_sub_dir="")
get directory
static dirsize($directory)
get size of a directory or a file.
$rest
Definition: goto.php:48
redirection script todo: (a better solution should control the processing via a xml file)
global $lng
Definition: privfeed.php:17
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
echo;exit;}function LogoutNotification($SessionID) { global $ilDB; $q="SELECT session_id, data FROM usr_session WHERE expires > (\w+)\|/" PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE
global $ilDB
$a_content
Definition: workflow.php:94