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 
12 require_once("./Services/FileSystem/classes/class.ilFileData.php");
13 require_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 
87  public function getAttachmentsTotalSizeLimit()
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(
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 }
$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:46
$size
Definition: RandomTest.php:84
unlinkFile($a_filename)
unlink one uploaded file expects a filename e.g &#39;foo&#39;
global $DIC
Definition: saml.php:7
__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)
if($format !==null) $name
Definition: metadata.php:146
getUserFilesData()
get all attachments of a specific user public
foreach($_POST as $key=> $value) $res
$a_content
Definition: workflow.php:93
This class handles all operations on files in directory /ilias_data/.
assignAttachmentsToDirectory($a_mail_id, $a_sent_mail_id)
assign attachments to mail directory
redirection script todo: (a better solution should control the processing via a xml file) ...
$query
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 $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