ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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{
25 public $user_id;
26
32 public $mail_path;
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 public function initDirectory()
64 {
65 if (is_writable($this->getPath())) {
66 if (mkdir($this->getPath() . '/' . MAILPATH)) {
67 if (chmod($this->getPath() . '/' . MAILPATH, 0755)) {
68 $this->mail_path = $this->getPath() . '/' . MAILPATH;
69 return true;
70 }
71 }
72 }
73 return false;
74 }
75
79 public function getUploadLimit()
80 {
82 }
83
88 {
89 $max_size = $this->ilias->getSetting('mail_maxsize_attach', '');
90 if (!strlen($max_size)) {
91 return null;
92 }
93
94 return (float) $this->ilias->getSetting('mail_maxsize_attach', 0) * 1024;
95 }
96
102 public function getMailPath()
103 {
104 return $this->mail_path;
105 }
106
111 {
112 return $this->mail_path . '/' . $this->user_id . '_';
113 }
114
122 public function getAttachmentPathByMD5Filename($a_filename, $a_mail_id)
123 {
124 global $ilDB;
125
126 /* $query = "SELECT path FROM mail_attachment ".
127 "WHERE mail_id = ".$ilDB->quote($a_mail_id)."";
128
129 $row = $this->ilias->db->getRow($query,ilDBConstants::FETCHMODE_OBJECT);
130 $path = $this->getMailPath().'/'.$row->path;
131 */
132 $query = $ilDB->query("SELECT path FROM mail_attachment
133 WHERE mail_id = " . $ilDB->quote($a_mail_id, 'integer') . "");
134
135 $rel_path = "";
136 while ($row = $ilDB->fetchObject($query)) {
137 $rel_path = $row->path;
138 $path = $this->getMailPath() . '/' . $row->path;
139 }
140
142 foreach ((array) $files as $file) {
143 if ($file['type'] == 'file' && md5($file['entry']) == $a_filename) {
144 return array(
145 'path' => $this->getMailPath() . '/' . $rel_path . '/' . $file['entry'],
146 'filename' => $file['entry']
147 );
148 }
149 }
150 return '';
151 }
152
153
161 public 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,ilDBConstants::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 $path = $this->getMailPath() . '/' . $row->path . '/' . $a_filename;
176 }
177
178 if (file_exists($path)) {
179 if (is_readable($path)) {
180 return $path;
181 }
182 return '';
183 }
184 return '';
185 }
193 public function adoptAttachments($a_attachments, $a_mail_id)
194 {
195 if (is_array($a_attachments)) {
196 foreach ($a_attachments as $file) {
197 $path = $this->getAttachmentPath($file, $a_mail_id);
198 if (!copy($path, $this->getMailPath() . '/' . $this->user_id . '_' . $file)) {
199 return "ERROR: $this->getMailPath().'/'.$this->user_id.'_'.$file cannot be created";
200 }
201 }
202 } else {
203 return "ARRAY REQUIRED";
204 }
205 return '';
206 }
207
214 public function checkReadWrite()
215 {
216 if (is_writable($this->mail_path) && is_readable($this->mail_path)) {
217 return true;
218 } else {
219 $this->ilias->raiseError("Mail directory is not readable/writable by webserver: " . $this->mail_path, $this->ilias->error_obj->FATAL);
220 }
221 }
227 public function getUserFilesData()
228 {
229 return $this->getUnsentFiles();
230 }
231
238 private function getUnsentFiles()
239 {
240 $files = array();
241
242 $iter = new DirectoryIterator($this->mail_path);
243 foreach ($iter as $file) {
247 if ($file->isFile()) {
248 list($uid, $rest) = explode('_', $file->getFilename(), 2);
249 if ($uid == $this->user_id) {
250 $files[] = array(
251 'name' => $rest,
252 'size' => $file->getSize(),
253 'ctime' => $file->getCTime()
254 );
255 }
256 }
257 }
258
259 return $files;
260 }
261
268 public function storeAsAttachment($a_filename, $a_content)
269 {
270 if (strlen($a_content) >= $this->getUploadLimit()) {
271 return 1;
272 }
273
274 $name = ilUtil::_sanitizeFilemame($a_filename);
275 $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $name);
276
277 $abs_path = $this->getMailPath() . '/' . $this->user_id . '_' . $name;
278
279 if (!$fp = @fopen($abs_path, 'w+')) {
280 return false;
281 }
282 if (@fwrite($fp, $a_content) === false) {
283 @fclose($fp);
284 return false;
285 }
286 @fclose($fp);
287 return true;
288 }
289
293 public function storeUploadedFile($file)
294 {
295 $file['name'] = ilUtil::_sanitizeFilemame($file['name']);
296
297 $this->rotateFiles($this->getMailPath() . '/' . $this->user_id . '_' . $file['name']);
298
299 ilUtil::moveUploadedFile(
300 $file['tmp_name'],
301 $file['name'],
302 $this->getMailPath() . '/' . $this->user_id . '_' . $file['name']
303 );
304 }
305
312 public function copyAttachmentFile($a_abs_path, $a_new_name)
313 {
314 @copy($a_abs_path, $this->getMailPath() . "/" . $this->user_id . "_" . $a_new_name);
315
316 return true;
317 }
318
319
320
328 public function rotateFiles($a_path)
329 {
330 if (file_exists($a_path)) {
331 $this->rotateFiles($a_path . ".old");
332 return \ilFileUtils::rename($a_path, $a_path . '.old');
333 }
334 return true;
335 }
342 public function unlinkFiles($a_filenames)
343 {
344 if (is_array($a_filenames)) {
345 foreach ($a_filenames as $file) {
346 if (!$this->unlinkFile($file)) {
347 return $file;
348 }
349 }
350 }
351 return '';
352 }
359 public function unlinkFile($a_filename)
360 {
361 if (file_exists($this->mail_path . '/' . basename($this->user_id . '_' . $a_filename))) {
362 return unlink($this->mail_path . '/' . basename($this->user_id . '_' . $a_filename));
363 }
364 }
371 public function getAbsolutePath($fileName)
372 {
373 return $this->getAbsoluteAttachmentPoolPathPrefix() . $fileName;
374 }
375
381 public function saveFiles($a_mail_id, array $a_attachments)
382 {
383 if (!is_numeric($a_mail_id) || $a_mail_id < 1) {
384 throw new InvalidArgumentException('The passed mail_id must be a valid integer!');
385 }
386
387 foreach ($a_attachments as $attachment) {
388 $this->saveFile($a_mail_id, $attachment);
389 }
390 }
391
392 public static function getStorage($a_mail_id, $a_usr_id)
393 {
394 static $fsstorage_cache = array();
395
396 if (!is_object($fsstorage_cache[$a_mail_id][$a_usr_id])) {
397 include_once 'Services/Mail/classes/class.ilFSStorageMail.php';
398 $fsstorage_cache[$a_mail_id][$a_usr_id] = new ilFSStorageMail($a_mail_id, $a_usr_id);
399 }
400
401 return $fsstorage_cache[$a_mail_id][$a_usr_id];
402 }
403
411 public function saveFile($a_mail_id, $a_attachment)
412 {
413 $oStorage = self::getStorage($a_mail_id, $this->user_id);
414 $oStorage->create();
415 $storage_directory = $oStorage->getAbsolutePath();
416
417 if (@!is_dir($storage_directory)) {
418 return false;
419 }
420
421 return copy(
422 $this->mail_path . '/' . $this->user_id . '_' . $a_attachment,
423 $storage_directory . '/' . $a_attachment
424 );
425 }
432 public function checkFilesExist($a_files)
433 {
434 if ($a_files) {
435 foreach ($a_files as $file) {
436 if (!file_exists($this->mail_path . '/' . $this->user_id . '_' . $file)) {
437 return false;
438 }
439 }
440 return true;
441 }
442 return true;
443 }
451 public function assignAttachmentsToDirectory($a_mail_id, $a_sent_mail_id)
452 {
453 global $ilDB;
454
455 /* $query = "INSERT INTO mail_attachment ".
456 "SET mail_id = ".$ilDB->quote($a_mail_id).", ".
457 "path = ".$ilDB->quote($this->user_id."_".$a_sent_mail_id)." ";
458 $res = $this->ilias->db->query($query);
459 */
460
461 $oStorage = self::getStorage($a_sent_mail_id, $this->user_id);
462 $res = $ilDB->manipulateF(
463 '
464 INSERT INTO mail_attachment
465 ( mail_id, path) VALUES (%s, %s)',
466 array('integer', 'text'),
467 array($a_mail_id, $oStorage->getRelativePathExMailDirectory())
468 );
469 }
476 public function deassignAttachmentFromDirectory($a_mail_id)
477 {
478 global $ilDB;
479 // IF IT'S THE LAST MAIL CONTAINING THESE ATTACHMENTS => DELETE ATTACHMENTS
480 $res = $ilDB->query("SELECT path FROM mail_attachment
481 WHERE mail_id = " . $ilDB->quote($a_mail_id, 'integer'));
482
483 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
484 $path = $row->path;
485 }
486 if ($path) {
487 $res = $ilDB->query("SELECT COUNT(mail_id) count_mail_id FROM mail_attachment
488 WHERE path = " . $ilDB->quote($path, 'text')) ;
489
490 while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
491 $cnt_mail_id = $row->count_mail_id;
492 }
493 if ($cnt_mail_id == 1) {
495 }
496 }
497
498 $res = $ilDB->manipulateF(
499 "DELETE FROM mail_attachment
500 WHERE mail_id = %s",
501 array('integer'),
502 array($a_mail_id)
503 );
504 return true;
505 }
506
507 public function __deleteAttachmentDirectory($a_rel_path)
508 {
509 ilUtil::delDir($this->mail_path . "/" . $a_rel_path);
510
511 return true;
512 }
513
517 protected function initAttachmentMaxUploadSize()
518 {
521 // Copy of ilFileInputGUI: begin
522 // get the value for the maximal uploadable filesize from the php.ini (if available)
523 $umf = ini_get("upload_max_filesize");
524 // get the value for the maximal post data from the php.ini (if available)
525 $pms = ini_get("post_max_size");
526
527 //convert from short-string representation to "real" bytes
528 $multiplier_a = array("K" => 1024, "M" => 1024 * 1024, "G" => 1024 * 1024 * 1024);
529
530 $umf_parts = preg_split("/(\d+)([K|G|M])/", $umf, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
531 $pms_parts = preg_split("/(\d+)([K|G|M])/", $pms, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
532
533 if (count($umf_parts) == 2) {
534 $umf = $umf_parts[0] * $multiplier_a[$umf_parts[1]];
535 }
536 if (count($pms_parts) == 2) {
537 $pms = $pms_parts[0] * $multiplier_a[$pms_parts[1]];
538 }
539
540 // use the smaller one as limit
541 $max_filesize = min($umf, $pms);
542
543 if (!$max_filesize) {
544 $max_filesize = max($umf, $pms);
545 }
546 // Copy of ilFileInputGUI: end
547
548 $this->mail_max_upload_file_size = $max_filesize;
549 }
550
559 public static function _lookupDiskUsageOfUser($user_id)
560 {
561 // XXX - This method is extremely slow. We should
562 // use a cache to speed it up, for example, we should
563 // store the disk space used in table mail_attachment.
564 global $DIC;
565
566 $mail_data_dir = ilUtil::getDataDir('filesystem') . DIRECTORY_SEPARATOR . "mail";
567
568 $q = "SELECT path " .
569 "FROM mail_attachment ma " .
570 "JOIN mail m ON ma.mail_id=m.mail_id " .
571 "WHERE m.user_id = " . $DIC->database()->quote($user_id);
572 $result_set = $DIC->database()->query($q);
573 $size = 0;
574 $count = 0;
575 while ($row = $result_set->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) {
576 $attachment_path = $mail_data_dir . DIRECTORY_SEPARATOR . $row['path'];
577 $attachment_size = ilUtil::dirsize($attachment_path);
578 if ($attachment_size != -1) {
579 $size += $attachment_size;
580 }
581 $count++;
582 }
583 return array('count'=>$count, 'size'=>$size);
584 }
585
589 public function onUserDelete()
590 {
594 global $ilDB;
595
596 // Delete uploaded mail files which are not attached to any message
597 try {
598 $iter = new RegexIterator(
599 new DirectoryIterator($this->getMailPath()),
600 '/^' . $this->user_id . '_/'
601 );
602 foreach ($iter as $file) {
607 if ($file->isFile()) {
608 @unlink($file->getPathname());
609 }
610 }
611 } catch (Exception $e) {
612 }
613
614 // Select all files attached to messages which are not shared (... = 1) with other messages anymore
615 $query = '
616 SELECT DISTINCT(ma1.path)
617 FROM mail_attachment ma1
618 INNER JOIN mail
619 ON mail.mail_id = ma1.mail_id
620 WHERE mail.user_id = %s
621 AND (SELECT COUNT(tmp.path) FROM mail_attachment tmp WHERE tmp.path = ma1.path) = 1
622 ';
623 $res = $ilDB->queryF(
624 $query,
625 array('integer'),
626 array($this->user_id)
627 );
628 while ($row = $ilDB->fetchAssoc($res)) {
629 try {
630 $path = $this->getMailPath() . DIRECTORY_SEPARATOR . $row['path'];
631 $iter = new RecursiveIteratorIterator(
632 new RecursiveDirectoryIterator($path),
633 RecursiveIteratorIterator::CHILD_FIRST
634 );
635 foreach ($iter as $file) {
640 if ($file->isDir()) {
641 @rmdir($file->getPathname());
642 } else {
643 @unlink($file->getPathname());
644 }
645 }
646 @rmdir($path);
647 } catch (Exception $e) {
648 }
649 }
650
651 // Delete each mail attachment rows assigned to a message of the deleted user.
652 $ilDB->manipulateF(
653 '
654 DELETE
655 FROM mail_attachment
656 WHERE EXISTS(
657 SELECT mail.mail_id
658 FROM mail
659 WHERE mail.user_id = %s AND mail.mail_id = mail_attachment.mail_id
660 )
661 ',
662 array('integer'),
663 array($this->user_id)
664 );
665 }
666}
$size
Definition: RandomTest.php:84
$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 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:46
if($format !==null) $name
Definition: metadata.php:146
redirection script todo: (a better solution should control the processing via a xml file)
$query
if(!file_exists("$old.txt")) if( $old===$new) if(file_exists("$new.txt")) $file
global $DIC
Definition: saml.php:7
foreach($_POST as $key=> $value) $res
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:93