19 declare(strict_types=1);
44 if (!defined(
'MAILPATH')) {
45 define(
'MAILPATH',
'mail');
49 $this->
ilias = $DIC[
'ilias'];
51 $this->user_id = $a_user_id;
53 $this->db = $DIC->database();
54 $this->tmpDirectory = $DIC->filesystem()->temp();
55 $this->storageDirectory = $DIC->filesystem()->storage();
62 if (is_writable($this->
getPath())
78 $max_size = $this->
ilias->getSetting(
'mail_maxsize_attach',
'');
79 if ($max_size ===
'') {
83 return (
float) $this->
ilias->getSetting(
'mail_maxsize_attach',
'0') * 1024;
93 return $this->mail_path .
'/' . $this->user_id .
'_';
102 $res = $this->db->queryF(
103 "SELECT path FROM mail_attachment WHERE mail_id = %s",
108 if (1 !== $this->db->numRows(
$res)) {
112 $row = $this->db->fetchAssoc(
$res);
114 $relativePath = $row[
'path'];
118 foreach ($files as $file) {
119 if ($file[
'type'] ===
'file' && md5($file[
'entry']) === $md5FileHash) {
121 'path' => $this->
getMailPath() .
'/' . $relativePath .
'/' . $file[
'entry'],
122 'filename' => $file[
'entry'],
133 $query = $this->db->query(
134 "SELECT path FROM mail_attachment WHERE mail_id = " . $this->db->quote($mailId,
'integer')
137 while ($row = $this->db->fetchObject(
$query)) {
148 if (is_readable(
$path)) {
163 foreach ($a_attachments as $file) {
165 if (!copy(
$path, $this->
getMailPath() .
'/' . $this->user_id .
'_' . $file)) {
166 return 'ERROR: ' . $this->
getMailPath() .
'/' . $this->user_id .
'_' . $file .
' cannot be created';
175 if (is_writable($this->mail_path) && is_readable($this->mail_path)) {
179 $this->
ilias->raiseError(
180 "Mail directory is not readable/writable by webserver: " .
182 $this->
ilias->error_obj->FATAL
193 return $this->getUnsentFiles();
199 private function getUnsentFiles(): array
203 $iter =
new RegexIterator(
new DirectoryIterator($this->mail_path),
"/^{$this->user_id}_(.+)$/");
204 foreach ($iter as $file) {
206 if (!$file->isFile()) {
210 [$uid,
$rest] = explode(
'_', $file->getFilename(), 2);
214 'size' => $file->getSize(),
215 'ctime' => $file->getCTime(),
228 'Mail upload limit reached for user with id %s',
239 $fp = fopen($abs_path,
'wb+');
240 if (!is_resource($fp)) {
243 'Could not read file: %s',
249 if (fwrite($fp, $a_content) ===
false) {
253 'Could not write file: %s',
276 $this->
getMailPath() .
'/' . $this->user_id .
'_' . $sanitized_filename
279 return $sanitized_filename;
290 @copy($a_abs_path, $this->
getMailPath() .
"/" . $this->user_id .
"_" . $a_new_name);
297 if (is_file($a_path)) {
311 foreach ($a_filenames as $file) {
322 if (is_file($this->mail_path .
'/' . basename($this->user_id .
'_' . $a_filename))) {
323 return unlink($this->mail_path .
'/' . basename($this->user_id .
'_' . $a_filename));
345 public function saveFiles(
int $a_mail_id, array $a_attachments): void
347 if (!is_numeric($a_mail_id) || $a_mail_id < 1) {
351 foreach ($a_attachments as $attachment) {
352 $this->
saveFile($a_mail_id, $attachment);
358 static $fsstorage_cache = [];
360 $fsstorage_cache[$a_mail_id][$a_usr_id] =
new ilFSStorageMail($a_mail_id, $a_usr_id);
362 return $fsstorage_cache[$a_mail_id][$a_usr_id];
371 public function saveFile(
int $a_mail_id,
string $a_attachment): bool
373 $oStorage = self::getStorage($a_mail_id, $this->user_id);
375 $storage_directory = $oStorage->getAbsolutePath();
377 if (!is_dir($storage_directory)) {
382 $this->mail_path .
'/' . $this->user_id .
'_' . $a_attachment,
383 $storage_directory .
'/' . $a_attachment
394 foreach ($a_files as $file) {
395 if (!is_file($this->mail_path .
'/' . $this->user_id .
'_' . $file)) {
408 $oStorage = self::getStorage($a_sent_mail_id, $this->user_id);
409 $res = $ilDB->manipulateF(
411 INSERT INTO mail_attachment 412 ( mail_id, path) VALUES (%s, %s)',
414 [$a_mail_id, $oStorage->getRelativePathExMailDirectory()]
423 'SELECT path FROM mail_attachment WHERE mail_id = ' .
424 $ilDB->quote($a_mail_id,
'integer')
429 $path = (string) $row->path;
434 'SELECT COUNT(mail_id) count_mail_id FROM mail_attachment WHERE path = ' .
435 $ilDB->quote(
$path,
'text')
440 $cnt_mail_id = (
int) $row->count_mail_id;
443 if ($cnt_mail_id === 1) {
449 'DELETE FROM mail_attachment WHERE mail_id = %s',
468 $umf = ini_get(
"upload_max_filesize");
470 $pms = ini_get(
"post_max_size");
473 $multiplier_a = [
"K" => 1024,
"M" => 1024 * 1024,
"G" => 1024 * 1024 * 1024];
475 $umf_parts = preg_split(
479 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
481 $pms_parts = preg_split(
485 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
488 if (count($umf_parts) === 2) {
489 $umf = (float) $umf_parts[0] * $multiplier_a[$umf_parts[1]];
491 if (count($pms_parts) === 2) {
492 $pms = (float) $pms_parts[0] * $multiplier_a[$pms_parts[1]];
496 $max_filesize = min($umf, $pms);
498 if (!$max_filesize) {
499 $max_filesize = max($umf, $pms);
502 $this->mail_max_upload_file_size = (
int) $max_filesize;
505 public function onUserDelete():
void 514 $iter =
new RegexIterator(
516 '/^' . $this->user_id .
'_/' 518 foreach ($iter as $file) {
523 if ($file->isFile()) {
524 @unlink($file->getPathname());
532 SELECT DISTINCT(ma1.path) 533 FROM mail_attachment ma1 535 ON mail.mail_id = ma1.mail_id 536 WHERE mail.user_id = %s 537 AND (SELECT COUNT(tmp.path) FROM mail_attachment tmp WHERE tmp.path = ma1.path) = 1 539 $res = $ilDB->queryF(
544 while ($row = $ilDB->fetchAssoc(
$res)) {
549 RecursiveIteratorIterator::CHILD_FIRST
551 foreach ($iter as $file) {
556 if ($file->isDir()) {
557 @rmdir($file->getPathname());
559 @unlink($file->getPathname());
575 WHERE mail.user_id = %s AND mail.mail_id = mail_attachment.mail_id 593 bool $isDraft =
false 599 throw new ilException(
'mail_download_zip_no_attachments');
604 if ($downloadFilename ===
'') {
605 $downloadFilename =
'attachments';
609 $relativeProcessingDirectory = basename($processingDirectory);
611 $absoluteZipDirectory = $processingDirectory .
'/' . $downloadFilename;
612 $relativeZipDirectory = $relativeProcessingDirectory .
'/' . $downloadFilename;
614 $this->tmpDirectory->createDir($relativeZipDirectory);
616 foreach ($files as $fileName) {
628 if (!$this->storageDirectory->has(
$source)) {
632 $target = $relativeZipDirectory .
'/' . $fileName;
634 $stream = $this->storageDirectory->readStream(
$source);
635 $this->tmpDirectory->writeStream($target, $stream);
638 $pathToZipFile = $processingDirectory .
'/' . $downloadFilename .
'.zip';
641 $this->tmpDirectory->deleteDir($relativeZipDirectory);
644 $processingDirectory .
'/' . $downloadFilename .
'.zip',
getAttachmentsTotalSizeLimit()
getAttachmentPathAndFilenameByMd5Hash(string $md5FileHash, int $mailId)
Filesystem $storageDirectory
storeAsAttachment(string $a_filename, string $a_content)
This class handles all operations on files (attachments) in directory ilias_data/mail.
Class ChatMainBarProvider .
adoptAttachments(array $a_attachments, int $a_mail_id)
Adopt attachments (in case of forwarding a mail)
static getValidFilename(string $a_filename)
copyAttachmentFile(string $a_abs_path, string $a_new_name)
Copy files in mail directory.
__construct(int $a_user_id=0)
static getASCIIFilename(string $a_filename)
getAttachmentPathByMailId(int $mailId)
static getStorage(int $a_mail_id, int $a_usr_id)
unlinkFile(string $a_filename)
static deliverFileAttached(string $path_to_file, ?string $download_file_name=null, ?string $mime_type=null, bool $delete_file=false)
assignAttachmentsToDirectory(int $a_mail_id, int $a_sent_mail_id)
rotateFiles(string $a_path)
getAbsoluteAttachmentPoolPathByFilename(string $fileName)
Resolves a path for a passed filename in regards of a user's mail attachment pool, meaning attachments not being sent.
deassignAttachmentFromDirectory(int $a_mail_id)
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively
deliverAttachmentsAsZip(string $basename, int $mailId, array $files=[], bool $isDraft=false)
unlinkFiles(array $a_filenames)
header include for all ilias files.
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory
static moveUploadedFile(string $a_file, string $a_name, string $a_target, bool $a_raise_errors=true, string $a_mode="move_uploaded")
move uploaded file
getAbsoluteAttachmentPoolPathPrefix()
static _sanitizeFilemame(string $a_filename)
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
int $mail_max_upload_file_size
__construct(Container $dic, ilPlugin $plugin)
static zip(string $a_dir, string $a_file, bool $compress_content=false)
zips given directory/file into given zip.file
storeUploadedFile(array $file)
static rename(string $a_source, string $a_target)
saveFiles(int $a_mail_id, array $a_attachments)
Saves all attachment files in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<us...
getAttachmentPath(string $a_filename, int $a_mail_id)
initAttachmentMaxUploadSize()
checkFilesExist(array $a_files)
saveFile(int $a_mail_id, string $a_attachment)
Save attachment file in a specific mail directory .../mail/<calculated_path>/mail_<mail_id>_<user_id>...
Class FlySystemFileAccessTest disabled disabled disabled.
deleteAttachmentDirectory(string $a_rel_path)