ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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
118 public function getAttachmentPathByMD5Filename($a_filename,$a_mail_id)
119 {
120 global $ilDB;
121
122/* $query = "SELECT path FROM mail_attachment ".
123 "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
124
125 $row = $this->ilias->db->getRow($query,DB_FETCHMODE_OBJECT);
126 $path = $this->getMailPath().'/'.$row->path;
127*/
128 $query = $ilDB->query("SELECT path FROM mail_attachment
129 WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer')."");
130
131 $rel_path = "";
132 while($row = $ilDB->fetchObject($query))
133 {
134 $rel_path = $row->path;
135 $path = $this->getMailPath().'/'.$row->path;
136
137 }
138
139 $files = ilUtil::getDir($path);
140 foreach((array)$files as $file)
141 {
142 if($file['type'] == 'file' && md5($file['entry']) == $a_filename)
143 {
144 return array(
145 'path' => $this->getMailPath().'/'.$rel_path.'/'.$file['entry'],
146 'filename' => $file['entry']
147 );
148 }
149 }
150 return '';
151 }
152
153
161 function getAttachmentPath($a_filename,$a_mail_id)
162 {
163 global $ilDB;
164
165/* $query = "SELECT path FROM mail_attachment ".
166 "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
167
168 $row = $this->ilias->db->getRow($query,DB_FETCHMODE_OBJECT);
169 $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
170*/
171 $query = $ilDB->query("SELECT path FROM mail_attachment ".
172 "WHERE mail_id = ".$ilDB->quote($a_mail_id, 'integer')."");
173
174 while($row = $ilDB->fetchObject($query))
175 {
176 $path = $this->getMailPath().'/'.$row->path.'/'.$a_filename;
177 }
178
179 if(file_exists($path))
180 {
181 if(is_readable($path))
182 {
183 return $path;
184 }
185 return '';
186 }
187 return '';
188 }
196 function adoptAttachments($a_attachments,$a_mail_id)
197 {
198 if(is_array($a_attachments))
199 {
200 foreach($a_attachments as $file)
201 {
202 $path = $this->getAttachmentPath($file,$a_mail_id);
203 if(!copy($path,$this->getMailPath().'/'.$this->user_id.'_'.$file))
204 {
205 return "ERROR: $this->getMailPath().'/'.$this->user_id.'_'.$file cannot be created";
206 }
207 }
208 }
209 else
210 {
211 return "ARRAY REQUIRED";
212 }
213 return '';
214 }
215
222 function checkReadWrite()
223 {
224 if(is_writable($this->mail_path) && is_readable($this->mail_path))
225 {
226 return true;
227 }
228 else
229 {
230 $this->ilias->raiseError("Mail directory is not readable/writable by webserver: ".$this->mail_path,$this->ilias->error_obj->FATAL);
231 }
232 }
239 {
240 return $this->getUnsentFiles();
241 }
242
249 private function getUnsentFiles()
250 {
251 $files = array();
252
253 $iter = new DirectoryIterator($this->mail_path);
254 foreach($iter as $file)
255 {
259 if($file->isFile())
260 {
261 list($uid, $rest) = explode('_', $file->getFilename(), 2);
262 if($uid == $this->user_id)
263 {
264 $files[] = array(
265 'name' => $rest,
266 'size' => $file->getSize(),
267 'ctime' => $file->getCTime()
268 );
269 }
270 }
271 }
272
273 return $files;
274 }
275
282 public function storeAsAttachment($a_filename,$a_content)
283 {
284 if(strlen($a_content) >= $this->getUploadLimit())
285 {
286 return 1;
287 }
288
289 $name = ilUtil::_sanitizeFilemame($a_filename);
290 $this->rotateFiles($this->getMailPath().'/'.$this->user_id.'_'.$name);
291
292 $abs_path = $this->getMailPath().'/'.$this->user_id.'_'.$name;
293
294 if(!$fp = @fopen($abs_path,'w+'))
295 {
296 return false;
297 }
298 if(@fwrite($fp,$a_content) === false)
299 {
300 @fclose($fp);
301 return false;
302 }
303 @fclose($fp);
304 return true;
305 }
306
310 public function storeUploadedFile($file)
311 {
312 $file['name'] = ilUtil::_sanitizeFilemame($file['name']);
313
314 $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $file['name']);
315
317 $file['tmp_name'],
318 $file['name'],
319 $this->getMailPath() . '/' . $this->user_id . '_' . $file['name']
320 );
321 }
322
329 function copyAttachmentFile($a_abs_path,$a_new_name)
330 {
331 @copy($a_abs_path,$this->getMailPath()."/".$this->user_id."_".$a_new_name);
332
333 return true;
334 }
335
336
337
345 function rotateFiles($a_path)
346 {
347 if(file_exists($a_path))
348 {
349 $this->rotateFiles($a_path.".old");
350 return \ilFileUtils::rename($a_path, $a_path . '.old');
351 }
352 return true;
353 }
360 function unlinkFiles($a_filenames)
361 {
362 if(is_array($a_filenames))
363 {
364 foreach($a_filenames as $file)
365 {
366 if(!$this->unlinkFile($file))
367 {
368 return $file;
369 }
370 }
371 }
372 return '';
373 }
380 function unlinkFile($a_filename)
381 {
382 if(file_exists($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename)))
383 {
384 return unlink($this->mail_path.'/'.basename($this->user_id.'_'.$a_filename));
385 }
386 }
393 function getAbsolutePath($a_path)
394 {
395 return $this->mail_path.'/'.$this->user_id.'_'.$a_path;
396 }
397
405 function saveFiles($a_mail_id,$a_attachments)
406 {
407 if(!$a_mail_id)
408 {
409 return "INTERNAL HERE ERROR: No valid mail_id given";
410 }
411 if(is_array($a_attachments))
412 {
413 foreach($a_attachments as $attachment)
414 {
415 if(!$this->saveFile($a_mail_id,$attachment))
416 {
417 return $attachment;
418 }
419 }
420 }
421 else
422 {
423 return "ARRAY REQUIRED";
424 }
425 return '';
426 }
427
428 public static function getStorage($a_mail_id, $a_usr_id)
429 {
430 static $fsstorage_cache = array();
431
432 if(!is_object($fsstorage_cache[$a_mail_id][$a_usr_id]))
433 {
434 include_once 'Services/Mail/classes/class.ilFSStorageMail.php';
435 $fsstorage_cache[$a_mail_id][$a_usr_id] = new ilFSStorageMail($a_mail_id, $a_usr_id);
436 }
437
438 return $fsstorage_cache[$a_mail_id][$a_usr_id];
439 }
440
448 function saveFile($a_mail_id,$a_attachment)
449 {
450 $oStorage = self::getStorage($a_mail_id, $this->user_id);
451 $oStorage->create();
452 $storage_directory = $oStorage->getAbsolutePath();
453
454 if(@!is_dir($storage_directory))
455 {
456 return false;
457 }
458
459 return copy($this->mail_path.'/'.$this->user_id.'_'.$a_attachment,
460 $storage_directory.'/'.$a_attachment);
461 }
468 function checkFilesExist($a_files)
469 {
470 if($a_files)
471 {
472 foreach($a_files as $file)
473 {
474 if(!file_exists($this->mail_path.'/'.$this->user_id.'_'.$file))
475 {
476 return false;
477 }
478 }
479 return true;
480 }
481 return true;
482 }
490 function assignAttachmentsToDirectory($a_mail_id,$a_sent_mail_id)
491 {
492 global $ilDB;
493
494/* $query = "INSERT INTO mail_attachment ".
495 "SET mail_id = ".$ilDB->quote($a_mail_id).", ".
496 "path = ".$ilDB->quote($this->user_id."_".$a_sent_mail_id)." ";
497 $res = $this->ilias->db->query($query);
498*/
499
500 $oStorage = self::getStorage($a_sent_mail_id, $this->user_id);
501 $res = $ilDB->manipulateF('
502 INSERT INTO mail_attachment
503 ( mail_id, path) VALUES (%s, %s)',
504 array('integer', 'text'),
505 array($a_mail_id, $oStorage->getRelativePathExMailDirectory())
506 );
507
508 }
516 {
517 global $ilDB;
518 // IF IT'S THE LAST MAIL CONTAINING THESE ATTACHMENTS => DELETE ATTACHMENTS
519 $res = $ilDB->query("SELECT path FROM mail_attachment
520 WHERE mail_id = ".$ilDB->quote($a_mail_id,'integer'));
521
522 while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
523 {
524 $path = $row->path;
525 }
526 if($path)
527 {
528 $res = $ilDB->query("SELECT COUNT(mail_id) count_mail_id FROM mail_attachment
529 WHERE path = ".$ilDB->quote($path,'text')) ;
530
531 while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
532 {
533 $cnt_mail_id = $row->count_mail_id;
534 }
535 if($cnt_mail_id == 1)
536 {
538 }
539 }
540
541 $res = $ilDB->manipulateF("DELETE FROM mail_attachment
542 WHERE mail_id = %s",
543 array('integer'),
544 array($a_mail_id));
545 return true;
546 }
547
548 function __deleteAttachmentDirectory($a_rel_path)
549 {
550 ilUtil::delDir($this->mail_path."/".$a_rel_path);
551
552 return true;
553 }
554
558 protected function initAttachmentMaxUploadSize()
559 {
562 // Copy of ilFileInputGUI: begin
563 // get the value for the maximal uploadable filesize from the php.ini (if available)
564 $umf = ini_get("upload_max_filesize");
565 // get the value for the maximal post data from the php.ini (if available)
566 $pms = ini_get("post_max_size");
567
568 //convert from short-string representation to "real" bytes
569 $multiplier_a = array("K" => 1024, "M" => 1024 * 1024, "G" => 1024 * 1024 * 1024);
570
571 $umf_parts = preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
572 $pms_parts = preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
573
574 if(count($umf_parts) == 2)
575 {
576 $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
577 }
578 if(count($pms_parts) == 2)
579 {
580 $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
581 }
582
583 // use the smaller one as limit
584 $max_filesize = min($umf, $pms);
585
586 if(!$max_filesize) $max_filesize = max($umf, $pms);
587 // Copy of ilFileInputGUI: end
588
589 $this->mail_max_upload_file_size = $max_filesize;
590 }
591
601 {
602 // XXX - This method is extremely slow. We should
603 // use a cache to speed it up, for example, we should
604 // store the disk space used in table mail_attachment.
605 global $ilDB, $lng;
606
607 $mail_data_dir = ilUtil::getDataDir('filesystem').DIRECTORY_SEPARATOR."mail";
608
609 $q = "SELECT path ".
610 "FROM mail_attachment ma ".
611 "JOIN mail m ON ma.mail_id=m.mail_id ".
612 "WHERE m.user_id = ".$ilDB->quote($user_id);
613 $result_set = $ilDB->query($q);
614 $size = 0;
615 $count = 0;
616 while($row = $result_set->fetchRow(DB_FETCHMODE_ASSOC))
617 {
618 $attachment_path = $mail_data_dir.DIRECTORY_SEPARATOR.$row['path'];
619 $attachment_size = ilUtil::dirsize($attachment_path);
620 if ($attachment_size != -1)
621 {
622 $size += $attachment_size;
623 }
624 $count++;
625 }
626 return array('count'=>$count, 'size'=>$size);
627 }
628
632 public function onUserDelete()
633 {
637 global $ilDB;
638
639 // Delete uploaded mail files which are not attached to any message
640 try
641 {
642 $iter = new RegexIterator(
643 new DirectoryIterator($this->getMailPath()), '/^'.$this->user_id.'_/'
644 );
645 foreach($iter as $file)
646 {
651 if($file->isFile())
652 {
653 @unlink($file->getPathname());
654 }
655 }
656 }
657 catch(Exception $e) { }
658
659 // Select all files attached to messages which are not shared (... = 1) with other messages anymore
660 $query = '
661 SELECT DISTINCT(ma1.path)
662 FROM mail_attachment ma1
663 INNER JOIN mail
664 ON mail.mail_id = ma1.mail_id
665 WHERE mail.user_id = %s
666 AND (SELECT COUNT(tmp.path) FROM mail_attachment tmp WHERE tmp.path = ma1.path) = 1
667 ';
668 $res = $ilDB->queryF(
669 $query,
670 array('integer'),
671 array($this->user_id)
672 );
673 while($row = $ilDB->fetchAssoc($res))
674 {
675 try
676 {
677 $path = $this->getMailPath().DIRECTORY_SEPARATOR.$row['path'];
678 $iter = new RecursiveIteratorIterator(
679 new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST
680 );
681 foreach($iter as $file)
682 {
687 if($file->isDir())
688 {
689 @rmdir($file->getPathname());
690 }
691 else
692 {
693 @unlink($file->getPathname());
694 }
695 }
696 @rmdir($path);
697 }
698 catch(Exception $e) { }
699 }
700
701 // Delete each mail attachment row assigned to a message of the deleted user.
702 if($ilDB->getDBType() == 'mysql' || $ilDB->getDBType() == 'innodb')
703 {
704 $ilDB->manipulateF('
705 DELETE m1
706 FROM mail_attachment m1
707 INNER JOIN (
708 SELECT mail_attachment.mail_id
709 FROM mail
710 INNER JOIN mail_attachment
711 ON mail_attachment.mail_id = mail.mail_id
712 WHERE user_id = %s
713 ) m2
714 ON m2.mail_id = m1.mail_id
715 ',
716 array('integer'),
717 array($this->user_id)
718 );
719 }
720 else
721 {
722 // Oracle and Postgres
723 $ilDB->manipulateF('
724 DELETE FROM mail_attachment
725 WHERE mail_attachment.mail_id IN (
726 SELECT mail_attachment.mail_id
727 FROM mail
728 INNER JOIN mail_attachment
729 ON mail_attachment.mail_id = mail.mail_id
730 WHERE user_id = %s
731 )
732 ',
733 array('integer'),
734 array($this->user_id)
735 );
736 }
737 }
738}
739?>
print $file
$size
Definition: RandomTest.php:79
const DB_FETCHMODE_ASSOC
Definition: class.ilDB.php:10
const DB_FETCHMODE_OBJECT
Definition: class.ilDB.php:11
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>...
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)
initDirectory()
init directory overwritten method @access public
saveFiles($a_mail_id, $a_attachments)
save all attachment files in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<use...
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.
_lookupDiskUsageOfUser($user_id)
Returns the number of bytes used on the harddisk for mail attachments, by the user with the specified...
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
getAbsolutePath($a_path)
get absolute path of filename
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
__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:85
redirection script todo: (a better solution should control the processing via a xml file)
global $lng
Definition: privfeed.php:40
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