ILIAS  trunk Revision v13.0_alpha-62-g3b72d83f2e5
ilFileDataMail Class Reference

Every resource of the mail stakeholder belongs to exactly one collection (pool, compose stage, draft, scheduled or sent mail). More...

+ Inheritance diagram for ilFileDataMail:
+ Collaboration diagram for ilFileDataMail:

Public Member Functions

 __construct (public int $user_id=0)
 
 getUploadLimit ()
 
 getAttachmentsTotalSizeLimit ()
 
 getMailPath ()
 
 getAbsoluteAttachmentPoolPathPrefix ()
 
 getAttachmentPathAndFilenameByMd5Hash (string $md5FileHash, int $mail_id)
 
 hasLegacyAttachmentDirectory (int $mail_id)
 
 checkReadWrite ()
 
 uploadToPool (UploadResult $result)
 
 getUserPoolRcid ()
 
 getUserPoolFilesData ()
 
 isLegacyPoolItemIdentifier (string $identifier)
 
 legacyPoolFilenameFromIdentifier (string $identifier)
 
 migrateLegacyPoolFilenameToResource (string $filename)
 
 resolvePoolIdentifiersToResources (array $identifiers)
 
 isInUserPool (ResourceIdentification $identification)
 
 adoptPoolResourcesToCollection (?ResourceCollectionIdentification $rcid, array $resource_identifications)
 
 removeFromPool (ResourceIdentification $rid)
 
 poolResourceHash (ResourceIdentification $rid)
 
 isCollectionReferenced (ResourceCollectionIdentification $rcid)
 A Mail collection is referenced as long as a mail (sent, received, draft, outbox), a compose stage or a user's attachment pool points to it. More...
 
 releaseCollectionIfUnreferenced (ResourceCollectionIdentification $rcid)
 Removes a Mail collection nobody references anymore, together with its resources. More...
 
 isCollectionExclusivelyOwnedByMail (ResourceCollectionIdentification $rcid)
 True if the collection can be handed over to delivered mails without copying it: it is Mail-owned and nobody references it. More...
 
 unlinkFile (string $a_filename)
 
 getAbsoluteAttachmentPoolPathByFilename (string $filename)
 Resolves a path for a passed filename in regards of a user's mail attachment pool, meaning attachments not being sent. More...
 
 checkFilesExist (array $a_files)
 
 assignAttachmentsToCollection (int $mail_id, ResourceCollectionIdentification $rcid)
 
 replaceMailAttachmentCollection (int $mail_id, ?ResourceCollectionIdentification $rcid)
 Points a mail (draft, outbox) to the passed collection (or to none). More...
 
 getRcidForMail (int $mail_id)
 
 deassignAttachmentFromDirectory (int $a_mail_id)
 
 deliverAttachmentsAsZip (string $basename, int $mail_id, array $files=[], bool $is_draft=false)
 
 getStakeholder ()
 
 canUseResourceInCompose (ResourceIdentification $identification)
 The compose form only shows files of the user's compose stage. More...
 
 addResourceToStage (ResourceIdentification $identification)
 Adds a just uploaded resource to the compose stage. More...
 
 removeFromStage (ResourceIdentification $identification)
 
 restrictStageTo (array $rid_strings)
 Removes all files from the compose stage which are not part of the submitted form. More...
 
 streamFromPath (string $absolute_path, ?string $revision_title=null)
 
 uploadToIrss (UploadResult $result)
 
 createCollectionFromPoolFilenames (array $filenames)
 
 migrateLegacyPoolAttachments (MailAttachments $attachments)
 
 adoptPoolFilenamesToCollection (?ResourceCollectionIdentification $rcid, array $filenames)
 
 createStageFromLegacyMailAttachments (int $mail_id, array $filenames)
 Creates a stage collection from a not yet migrated (directory based) mail, e.g. More...
 
 createCollectionFromContent (string $name, string $content)
 
 copyCollection (ResourceCollectionIdentification $source)
 Copies all files of the passed collection (of the mail system or of another component) into a new collection of the mail system. More...
 
 applyPoolSelectionToStage (array $selected_pool_resources)
 Applies a selection of the attachment pool to the compose stage: pool files are matched by their hashed name, selected files missing in the stage are copied into it, deselected ones are removed. More...
 
 getPoolResourcesInStage (ResourceCollectionIdentification $stage_rcid)
 
 getCollection (ResourceCollectionIdentification $rcid)
 
 getResourceIdByHash (ResourceCollectionIdentification $rcid, string $hash)
 
 getRidsFromCollection (ResourceCollectionIdentification $rcid)
 
 getAttachmentListing (ResourceCollectionIdentification $rcid)
 Keyed by resource id. More...
 
 deliverFile (ResourceCollectionIdentification $rcid, string $md5_hash)
 
 deliverCollectionAsZip (ResourceCollectionIdentification $rcid, string $zip_basename)
 
 removeCollection (ResourceCollectionIdentification $rcid, bool $delete_resources=false)
 Removes the collection. More...
 
 releaseSourceCollectionAfterDelivery (ResourceCollectionIdentification $rcid)
 Drops the source collection after it has been delivered. More...
 
 getIrssMimeAttachments (ResourceCollectionIdentification $rcid)
 
- Public Member Functions inherited from ilFileData
 __construct ()
 
 checkPath (string $a_path)
 
 getPath ()
 
- Public Member Functions inherited from ilFile
 deleteTrailingSlash (string $a_path)
 delete trailing slash of path variables More...
 

Data Fields

const string POOL_RCID_PREF_KEY = 'mail_attachment_pool_rcid'
 
const string LEGACY_POOL_ITEM_PREFIX = 'legacy:'
 
string $mail_path
 

Protected Member Functions

 initAttachmentMaxUploadSize ()
 

Protected Attributes

int $mail_max_upload_file_size
 
Filesystem $tmp_directory
 
Filesystem $storage_directory
 
ilDBInterface $db
 
ILIAS $ilias
 
- Protected Attributes inherited from ilFile
string $path
 

Private Member Functions

 getAttachmentPathByMailId (int $mail_id)
 
 addResourceToPool (ResourceIdentification $rid)
 Adds a resource to the user's pool. More...
 
 resolveUserPoolRcid ()
 
 resolveStageRcid ()
 
 collectionContainsResource (?ResourceCollectionIdentification $rcid, ResourceIdentification $identification)
 
 iteratePoolResourceIdentifications (ResourceCollectionIdentification $pool_rcid)
 
 persistUserPoolRcid (ResourceCollectionIdentification $rcid)
 
 deleteResource (ResourceIdentification $rid)
 
 isValidAttachmentPoolFilename (string $filename)
 
 getRcidForMailOfUser (int $mail_id)
 
 deleteAttachmentDirectory (string $a_rel_path)
 
 createCollectionFromResourceIdentifications (array $resource_identifications)
 
 getUserPoolResources ()
 
 copyResources (array $resource_identifications)
 
 loadPoolCollectionForMutation (?ResourceCollectionIdentification $pool_rcid)
 
 getAssignedRidStrings (ResourceCollectionIdentification $rcid)
 
 collectionIsKnown (ResourceCollectionIdentification $rcid)
 
 attachmentHash (ResourceIdentification $identification)
 Unique per resource: equal file names in one collection must stay distinguishable. More...
 
 resourceIdByHashInCollection (ResourceCollection $collection, string $hash)
 
 applyResourceFileName (ResourceIdentification $rid, string $file_name)
 
 resourceHasOnlyMailStakeholder (ResourceIdentification $rid)
 

Private Attributes

readonly Services $irss
 
readonly ilMailAttachmentStakeholder $stakeholder
 

Detailed Description

Every resource of the mail stakeholder belongs to exactly one collection (pool, compose stage, draft, scheduled or sent mail).

Collections are copied when they change hands, so releasing a collection that no mail, stage or pool references removes its resources as well.

Definition at line 37 of file class.ilFileDataMail.php.

Constructor & Destructor Documentation

◆ __construct()

ilFileDataMail::__construct ( public int  $user_id = 0)

Definition at line 51 of file class.ilFileDataMail.php.

52 {
53 global $DIC;
54
55 if (!defined('MAILPATH')) {
56 define('MAILPATH', 'mail');
57 }
59 $this->mail_path = $this->getPath() . '/' . MAILPATH;
60 $this->ilias = $DIC['ilias'];
61 $this->db = $DIC->database();
62 $this->tmp_directory = $DIC->filesystem()->temp();
63 $this->storage_directory = $DIC->filesystem()->storage();
64 $this->irss = $DIC->resourceStorage();
65 $this->stakeholder = new ilMailAttachmentStakeholder();
66 $this->stakeholder->setOwner($this->user_id);
67
68 $this->checkReadWrite();
70 }
const MAILPATH
Definition: constants.php:50
__construct(Container $dic, ilPlugin $plugin)
@inheritDoc
Class ilObjForumAdministration.
global $DIC
Definition: shib_login.php:26

References $DIC, ILIAS\GlobalScreen\Provider\__construct(), checkReadWrite(), ilFileData\getPath(), initAttachmentMaxUploadSize(), and MAILPATH.

+ Here is the call graph for this function:

Member Function Documentation

◆ addResourceToPool()

ilFileDataMail::addResourceToPool ( ResourceIdentification  $rid)
private

Adds a resource to the user's pool.

A pool file with the same name is replaced, like the legacy pool overwrote files with the same name.

Definition at line 224 of file class.ilFileDataMail.php.

225 {
226 $pool_rcid = $this->resolveUserPoolRcid();
227 if ($pool_rcid !== null) {
228 $existing = $this->resourceIdByHashInCollection(
229 $this->getCollection($pool_rcid),
230 $this->poolResourceHash($rid)
231 );
232 if ($existing !== null && $existing->serialize() !== $rid->serialize()) {
233 $this->removeFromPool($existing);
234 }
235 }
236
237 $updated_rcid = $this->adoptPoolResourcesToCollection($pool_rcid, [$rid]);
238 if ($updated_rcid === null) {
239 $this->deleteResource($rid);
240 throw new RuntimeException('Could not store mail attachment in pool.');
241 }
242
243 if ($pool_rcid === null || $pool_rcid->serialize() !== $updated_rcid->serialize()) {
244 $this->persistUserPoolRcid($updated_rcid);
245 }
246
247 return $rid;
248 }
poolResourceHash(ResourceIdentification $rid)
getCollection(ResourceCollectionIdentification $rcid)
deleteResource(ResourceIdentification $rid)
adoptPoolResourcesToCollection(?ResourceCollectionIdentification $rcid, array $resource_identifications)
persistUserPoolRcid(ResourceCollectionIdentification $rcid)
removeFromPool(ResourceIdentification $rid)
resourceIdByHashInCollection(ResourceCollection $collection, string $hash)

References adoptPoolResourcesToCollection(), deleteResource(), getCollection(), persistUserPoolRcid(), poolResourceHash(), removeFromPool(), resolveUserPoolRcid(), resourceIdByHashInCollection(), and ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

Referenced by uploadToPool().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ addResourceToStage()

ilFileDataMail::addResourceToStage ( ResourceIdentification  $identification)

Adds a just uploaded resource to the compose stage.

The returned collection must be persisted as stage if it was created.

Definition at line 1014 of file class.ilFileDataMail.php.

1015 {
1016 $stage_rcid = $this->resolveStageRcid();
1017 $collection = $stage_rcid !== null && $this->collectionIsKnown($stage_rcid)
1018 ? $this->getCollection($stage_rcid)
1019 : $this->irss->collection()->get($this->irss->collection()->id(null, $this->user_id));
1020
1021 $collection->add($identification);
1022 $this->irss->collection()->store($collection);
1023
1024 return $collection->getIdentification();
1025 }
collectionIsKnown(ResourceCollectionIdentification $rcid)
get(string $class_name)

◆ adoptPoolFilenamesToCollection()

ilFileDataMail::adoptPoolFilenamesToCollection ( ?ResourceCollectionIdentification  $rcid,
array  $filenames 
)
Parameters
list<string>$filenames Pool filenames without user prefix

Definition at line 1136 of file class.ilFileDataMail.php.

1140 if ($filenames === []) {
1141 return null;
1142 }
1143
1144 if ($rcid !== null && $this->irss->collection()->exists($rcid->serialize())) {
1145 $collection_id = $this->irss->collection()->id($rcid->serialize(), $this->user_id);
1146 } else {
1147 $collection_id = $this->irss->collection()->id(null, $this->user_id);
1148 }
1149
1150 $collection = $this->irss->collection()->get($collection_id);
1151 $added = false;
1152
1153 foreach ($filenames as $filename) {
1155 if (!is_file($path)) {
1156 continue;
1157 }
1158
1159 $hash = md5($filename);
1160 if ($this->resourceIdByHashInCollection($collection, $hash) !== null) {
1161 continue;
1162 }
1163
1164 $resource_identification = $this->streamFromPath($path, $hash);
1165 $this->applyResourceFileName($resource_identification, $filename);
1166 $collection->add($resource_identification);
1167 $added = true;
1168 }
1169
1170 if (!$added) {
1171 return null;
1172 }
1173
1174 $this->irss->collection()->store($collection);
1175
1176 return $collection->getIdentification();
1177 }
$filename
Definition: buildRTE.php:78
streamFromPath(string $absolute_path, ?string $revision_title=null)
getAbsoluteAttachmentPoolPathByFilename(string $filename)
Resolves a path for a passed filename in regards of a user's mail attachment pool,...
applyResourceFileName(ResourceIdentification $rid, string $file_name)
string $path

◆ adoptPoolResourcesToCollection()

ilFileDataMail::adoptPoolResourcesToCollection ( ?ResourceCollectionIdentification  $rcid,
array  $resource_identifications 
)
Parameters
list<ResourceIdentification>$resource_identifications

Definition at line 420 of file class.ilFileDataMail.php.

424 if ($resource_identifications === []) {
425 return null;
426 }
427
428 $collection = $this->loadPoolCollectionForMutation($rcid);
429 $added = false;
430
431 foreach ($resource_identifications as $resource_identification) {
432 $hash = $this->irss->manage()->getCurrentRevision($resource_identification)->getTitle();
433 if ($this->resourceIdByHashInCollection($collection, $hash) !== null) {
434 continue;
435 }
436
437 $collection->add($resource_identification);
438 $added = true;
439 }
440
441 if (!$added) {
442 return null;
443 }
444
445 $this->irss->collection()->store($collection);
446
447 return $collection->getIdentification();
448 }
loadPoolCollectionForMutation(?ResourceCollectionIdentification $pool_rcid)

Referenced by addResourceToPool().

+ Here is the caller graph for this function:

◆ applyPoolSelectionToStage()

ilFileDataMail::applyPoolSelectionToStage ( array  $selected_pool_resources)

Applies a selection of the attachment pool to the compose stage: pool files are matched by their hashed name, selected files missing in the stage are copied into it, deselected ones are removed.

Parameters
list<ResourceIdentification>$selected_pool_resources

Definition at line 1267 of file class.ilFileDataMail.php.

1268 {
1269 $pool_hashes = [];
1270 foreach ($this->getUserPoolResources() as $pool_resource) {
1271 $pool_hashes[$this->poolResourceHash($pool_resource)] = true;
1272 }
1273
1274 $selected = [];
1275 foreach ($selected_pool_resources as $pool_resource) {
1276 $selected[$this->poolResourceHash($pool_resource)] = $pool_resource;
1277 }
1278
1279 $stage_rcid = $this->resolveStageRcid();
1280 $collection = $stage_rcid !== null && $this->collectionIsKnown($stage_rcid)
1281 ? $this->getCollection($stage_rcid)
1282 : $this->irss->collection()->get($this->irss->collection()->id(null, $this->user_id));
1283
1284 $removed = [];
1285 foreach ($collection->getResourceIdentifications() as $identification) {
1286 $hash = $this->poolResourceHash($identification);
1287 if (isset($pool_hashes[$hash]) && !isset($selected[$hash])) {
1288 $collection->remove($identification);
1289 $removed[] = $identification;
1290 continue;
1291 }
1292 unset($selected[$hash]);
1293 }
1294
1295 foreach ($this->copyResources(array_values($selected)) as $copy) {
1296 $collection->add($copy);
1297 }
1298
1299 $this->irss->collection()->store($collection);
1300 foreach ($removed as $identification) {
1301 $this->deleteResource($identification);
1302 }
1303
1304 return $collection->count() > 0 ? $collection->getIdentification() : null;
1305 }
copyResources(array $resource_identifications)

◆ applyResourceFileName()

ilFileDataMail::applyResourceFileName ( ResourceIdentification  $rid,
string  $file_name 
)
private

Definition at line 1550 of file class.ilFileDataMail.php.

1550 : void
1551 {
1552 if ($file_name === '') {
1553 return;
1554 }
1555
1556 $revision = $this->irss->manage()->getCurrentRevision($rid);
1557 $information = $revision->getInformation();
1558 if (!$information instanceof FileInformation) {
1559 return;
1560 }
1561 $information->setTitle($file_name);
1562 $suffix = pathinfo($file_name, PATHINFO_EXTENSION);
1563 if ($suffix !== '') {
1564 $information->setSuffix($suffix);
1565 }
1566 $revision->setInformation($information);
1567 $this->irss->manage()->updateRevision($revision);
1568 }

◆ assignAttachmentsToCollection()

ilFileDataMail::assignAttachmentsToCollection ( int  $mail_id,
ResourceCollectionIdentification  $rcid 
)

Definition at line 633 of file class.ilFileDataMail.php.

636 : void {
637 $this->db->manipulateF(
638 'INSERT INTO mail_attachment (mail_id, path, rcid) VALUES (%s, %s, %s)',
640 [$mail_id, '', $rcid->serialize()]
641 );
642 }

◆ attachmentHash()

ilFileDataMail::attachmentHash ( ResourceIdentification  $identification)
private

Unique per resource: equal file names in one collection must stay distinguishable.

Definition at line 1443 of file class.ilFileDataMail.php.

1443 : string
1444 {
1445 return md5($identification->serialize());
1446 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

+ Here is the call graph for this function:

◆ canUseResourceInCompose()

ilFileDataMail::canUseResourceInCompose ( ResourceIdentification  $identification)

The compose form only shows files of the user's compose stage.

Definition at line 1005 of file class.ilFileDataMail.php.

1005 : bool
1006 {
1007 return $this->collectionContainsResource($this->resolveStageRcid(), $identification);
1008 }
collectionContainsResource(?ResourceCollectionIdentification $rcid, ResourceIdentification $identification)

◆ checkFilesExist()

ilFileDataMail::checkFilesExist ( array  $a_files)
Parameters
list<string>$a_files

Definition at line 620 of file class.ilFileDataMail.php.

620 : bool
621 {
622 if ($a_files !== []) {
623 foreach ($a_files as $file) {
624 if (!is_file($this->mail_path . '/' . $this->user_id . '_' . $file)) {
625 return false;
626 }
627 }
628 }
629
630 return true;
631 }

◆ checkReadWrite()

ilFileDataMail::checkReadWrite ( )

Definition at line 171 of file class.ilFileDataMail.php.

171 : bool
172 {
173 if (is_writable($this->mail_path) && is_readable($this->mail_path)) {
174 return true;
175 }
176
177 $this->ilias->raiseError(
178 'Mail directory is not readable/writable by webserver: ' .
179 $this->mail_path,
180 $this->ilias->error_obj->FATAL
181 );
182
183 return false;
184 }

Referenced by __construct().

+ Here is the caller graph for this function:

◆ collectionContainsResource()

ilFileDataMail::collectionContainsResource ( ?ResourceCollectionIdentification  $rcid,
ResourceIdentification  $identification 
)
private

Definition at line 295 of file class.ilFileDataMail.php.

298 : bool {
299 if ($rcid === null) {
300 return false;
301 }
302
303 return in_array($identification->serialize(), $this->getAssignedRidStrings($rcid), true);
304 }

◆ collectionIsKnown()

ilFileDataMail::collectionIsKnown ( ResourceCollectionIdentification  $rcid)
private

Definition at line 1406 of file class.ilFileDataMail.php.

1406 : bool
1407 {
1408 return $this->irss->collection()->exists($rcid->serialize());
1409 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

Referenced by resolveUserPoolRcid().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ copyCollection()

ilFileDataMail::copyCollection ( ResourceCollectionIdentification  $source)

Copies all files of the passed collection (of the mail system or of another component) into a new collection of the mail system.

The source stays untouched.

Definition at line 1247 of file class.ilFileDataMail.php.

1248 {
1249 if (!$this->collectionIsKnown($source)) {
1250 return null;
1251 }
1252
1253 $copies = $this->copyResources(array_values($this->getCollection($source)->getResourceIdentifications()));
1254 if ($copies === []) {
1255 return null;
1256 }
1257
1258 return $this->createCollectionFromResourceIdentifications($copies);
1259 }
createCollectionFromResourceIdentifications(array $resource_identifications)

◆ copyResources()

ilFileDataMail::copyResources ( array  $resource_identifications)
private
Parameters
list<ResourceIdentification>$resource_identifications
Returns
list<ResourceIdentification>

Definition at line 1347 of file class.ilFileDataMail.php.

1347 : array
1348 {
1349 $copies = [];
1350 foreach ($resource_identifications as $source) {
1351 $revision = $this->irss->manage()->getCurrentRevision($source);
1352 $stream = $this->irss->consume()->stream($source);
1353 $copy = $this->irss->manage()->stream(
1354 $stream->getStream(),
1355 $this->stakeholder,
1356 $revision->getTitle()
1357 );
1358 $this->applyResourceFileName($copy, $revision->getInformation()->getTitle());
1359 $copies[] = $copy;
1360 }
1361
1362 return $copies;
1363 }

◆ createCollectionFromContent()

ilFileDataMail::createCollectionFromContent ( string  $name,
string  $content 
)

Definition at line 1217 of file class.ilFileDataMail.php.

1218 {
1219 if ($name === '' || $content === '') {
1220 return null;
1221 }
1222
1223 if (strlen($content) >= $this->getUploadLimit()) {
1224 throw new DomainException(
1225 sprintf(
1226 'Mail upload limit reached for user with id %s',
1227 $this->user_id
1228 )
1229 );
1230 }
1231
1232 $sanitized_name = ilFileUtils::_sanitizeFilemame($name);
1233 $resource_identification = $this->irss->manage()->stream(
1234 Streams::ofString($content),
1235 $this->stakeholder,
1236 md5($sanitized_name)
1237 );
1238 $this->applyResourceFileName($resource_identification, $sanitized_name);
1239
1240 return $this->createCollectionFromResourceIdentifications([$resource_identification]);
1241 }
static _sanitizeFilemame(string $a_filename)

References ilFileUtils\_sanitizeFilemame().

+ Here is the call graph for this function:

◆ createCollectionFromPoolFilenames()

ilFileDataMail::createCollectionFromPoolFilenames ( array  $filenames)
Parameters
list<string>$filenames Pool filenames without user prefix

Definition at line 1113 of file class.ilFileDataMail.php.

1114 {
1115 return $this->adoptPoolFilenamesToCollection(null, $filenames);
1116 }
adoptPoolFilenamesToCollection(?ResourceCollectionIdentification $rcid, array $filenames)

◆ createCollectionFromResourceIdentifications()

ilFileDataMail::createCollectionFromResourceIdentifications ( array  $resource_identifications)
private
Parameters
list<ResourceIdentification>$resource_identifications Resources not yet part of any collection

Definition at line 1097 of file class.ilFileDataMail.php.

1100 $rcid = $this->irss->collection()->id(null, $this->user_id);
1101 $collection = $this->irss->collection()->get($rcid);
1102 foreach ($resource_identifications as $resource_identification) {
1103 $collection->add($resource_identification);
1104 }
1105 $this->irss->collection()->store($collection);
1106
1107 return $collection->getIdentification();
1108 }

◆ createStageFromLegacyMailAttachments()

ilFileDataMail::createStageFromLegacyMailAttachments ( int  $mail_id,
array  $filenames 
)

Creates a stage collection from a not yet migrated (directory based) mail, e.g.

when forwarding it.

Parameters
list<string>$filenames

Definition at line 1184 of file class.ilFileDataMail.php.

1185 {
1186 // Without a directory the files are gone, the names must not resolve to the forwarding user's pool
1187 if (!$this->hasLegacyAttachmentDirectory($mail_id)) {
1188 return MailAttachments::empty();
1189 }
1190
1191 $resource_identifications = [];
1192 foreach ($filenames as $filename) {
1193 try {
1194 $file = $this->getAttachmentPathAndFilenameByMd5Hash(md5($filename), $mail_id);
1195 } catch (OutOfBoundsException) {
1196 continue;
1197 }
1198
1199 if (isset($file['rcid']) && $file['rcid'] instanceof ResourceCollectionIdentification) {
1200 $rcid = $this->copyCollection($file['rcid']);
1201
1202 return $rcid !== null ? MailAttachments::fromIrss($rcid) : MailAttachments::empty();
1203 }
1204
1205 if (is_file($file['path'])) {
1206 $resource_identifications[] = $this->streamFromPath($file['path'], md5($file['filename']));
1207 }
1208 }
1209
1210 if ($resource_identifications === []) {
1211 return MailAttachments::empty();
1212 }
1213
1214 return MailAttachments::fromIrss($this->createCollectionFromResourceIdentifications($resource_identifications));
1215 }
copyCollection(ResourceCollectionIdentification $source)
Copies all files of the passed collection (of the mail system or of another component) into a new col...
getAttachmentPathAndFilenameByMd5Hash(string $md5FileHash, int $mail_id)
hasLegacyAttachmentDirectory(int $mail_id)

References $filename.

◆ deassignAttachmentFromDirectory()

ilFileDataMail::deassignAttachmentFromDirectory ( int  $a_mail_id)

Definition at line 710 of file class.ilFileDataMail.php.

710 : bool
711 {
712 $res = $this->db->query(
713 'SELECT path, rcid FROM mail_attachment WHERE mail_id = ' . $this->db->quote($a_mail_id, 'integer')
714 );
715
716 $path = '';
717 $rcid = '';
718 while ($row = $this->db->fetchObject($res)) {
719 $path = (string) $row->path;
720 $rcid = (string) ($row->rcid ?? '');
721 }
722
723 if ($rcid !== '' && $rcid !== '-') {
724 $this->db->manipulateF(
725 'DELETE FROM mail_attachment WHERE mail_id = %s',
726 ['integer'],
727 [$a_mail_id]
728 );
730
731 return true;
732 }
733
734 if ($path !== '') {
735 $res = $this->db->query(
736 'SELECT COUNT(mail_id) count_mail_id FROM mail_attachment WHERE path = ' .
737 $this->db->quote($path, 'text')
738 );
739
740 $cnt_mail_id = 0;
741 while ($row = $this->db->fetchObject($res)) {
742 $cnt_mail_id = (int) $row->count_mail_id;
743 }
744
745 if ($cnt_mail_id === 1) {
747 }
748 }
749
750 $this->db->manipulateF(
751 'DELETE FROM mail_attachment WHERE mail_id = %s',
752 ['integer'],
753 [$a_mail_id]
754 );
755
756 return true;
757 }
deleteAttachmentDirectory(string $a_rel_path)
releaseCollectionIfUnreferenced(ResourceCollectionIdentification $rcid)
Removes a Mail collection nobody references anymore, together with its resources.
foreach($_POST as $key=> $value) $res

References $res, and ILIAS\Repository\int().

+ Here is the call graph for this function:

◆ deleteAttachmentDirectory()

ilFileDataMail::deleteAttachmentDirectory ( string  $a_rel_path)
private

Definition at line 759 of file class.ilFileDataMail.php.

759 : void
760 {
761 ilFileUtils::delDir($this->mail_path . '/' . $a_rel_path);
762 }
static delDir(string $a_dir, bool $a_clean_only=false)
removes a dir and all its content (subdirs and files) recursively

References ilFileUtils\delDir().

+ Here is the call graph for this function:

◆ deleteResource()

ilFileDataMail::deleteResource ( ResourceIdentification  $rid)
private

Definition at line 551 of file class.ilFileDataMail.php.

551 : void
552 {
553 $this->irss->manage()->remove($rid, $this->stakeholder);
554 }

Referenced by addResourceToPool().

+ Here is the caller graph for this function:

◆ deliverAttachmentsAsZip()

ilFileDataMail::deliverAttachmentsAsZip ( string  $basename,
int  $mail_id,
array  $files = [],
bool  $is_draft = false 
)
Parameters
list<string>$files

Definition at line 930 of file class.ilFileDataMail.php.

935 : void {
936 $rcid = $this->getRcidForMail($mail_id);
937 if ($rcid !== null && !$is_draft) {
938 $this->deliverCollectionAsZip($rcid, $basename);
939
940 return;
941 }
942
943 $path = '';
944 if (!$is_draft) {
945 $path = $this->getAttachmentPathByMailId($mail_id);
946 if ($path === '') {
947 throw new ilMailException('mail_download_zip_no_attachments');
948 }
949 }
950
951 $download_filename = ilFileUtils::getASCIIFilename($basename);
952 if ($download_filename === '') {
953 $download_filename = 'attachments';
954 }
955
956 $processing_directory = ilFileUtils::ilTempnam();
957 $relative_processing_directory = basename($processing_directory);
958
959 $absolute_zip_directory = $processing_directory . '/' . $download_filename;
960 $relative_zip_directory = $relative_processing_directory . '/' . $download_filename;
961
962 $this->tmp_directory->createDir($relative_zip_directory);
963
964 foreach ($files as $filename) {
965 if ($is_draft) {
966 $source = str_replace(
967 $this->mail_path,
968 MAILPATH,
970 );
971 } else {
972 $source = MAILPATH . '/' . $path . '/' . $filename;
973 }
974
975 $source = str_replace('//', '/', $source);
976 if (!$this->storage_directory->has($source)) {
977 continue;
978 }
979
980 $target = $relative_zip_directory . '/' . $filename;
981
982 $stream = $this->storage_directory->readStream($source);
983 $this->tmp_directory->writeStream($target, $stream);
984 }
985
986 $path_to_zip_file = $processing_directory . '/' . $download_filename . '.zip';
987 ilFileUtils::zip($absolute_zip_directory, $path_to_zip_file);
988
989 $this->tmp_directory->deleteDir($relative_zip_directory);
990
992 $processing_directory . '/' . $download_filename . '.zip',
993 ilFileUtils::getValidFilename($download_filename . '.zip')
994 );
995 }
getAttachmentPathByMailId(int $mail_id)
getRcidForMail(int $mail_id)
deliverCollectionAsZip(ResourceCollectionIdentification $rcid, string $zip_basename)
static deliverFileAttached(string $path_to_file, ?string $download_file_name=null, ?string $mime_type=null, bool $delete_file=false)
static getASCIIFilename(string $a_filename)
static zip(string $a_dir, string $a_file, bool $compress_content=false)
static ilTempnam(?string $a_temp_path=null)
Returns a unique and non existing Path for e temporary file or directory.
static getValidFilename(string $a_filename)

◆ deliverCollectionAsZip()

ilFileDataMail::deliverCollectionAsZip ( ResourceCollectionIdentification  $rcid,
string  $zip_basename 
)

Definition at line 1513 of file class.ilFileDataMail.php.

1513 : void
1514 {
1515 $zip_filename = FileDelivery::returnASCIIFileName($zip_basename . '.zip');
1516 $this->irss
1517 ->consume()
1518 ->downloadCollection($rcid, $zip_filename)
1519 ->useRevisionTitlesForFileNames(false)
1520 ->run();
1521 }

◆ deliverFile()

ilFileDataMail::deliverFile ( ResourceCollectionIdentification  $rcid,
string  $md5_hash 
)

Definition at line 1503 of file class.ilFileDataMail.php.

1503 : void
1504 {
1505 $resource_identification = $this->getResourceIdByHash($rcid, $md5_hash);
1506 if ($resource_identification === null) {
1507 throw new OutOfBoundsException('mail_error_reading_attachment');
1508 }
1509
1510 $this->irss->consume()->download($resource_identification)->run();
1511 }
getResourceIdByHash(ResourceCollectionIdentification $rcid, string $hash)

◆ getAbsoluteAttachmentPoolPathByFilename()

ilFileDataMail::getAbsoluteAttachmentPoolPathByFilename ( string  $filename)

Resolves a path for a passed filename in regards of a user's mail attachment pool, meaning attachments not being sent.

Definition at line 600 of file class.ilFileDataMail.php.

600 : string
601 {
603 throw new InvalidArgumentException('The passed filename must not contain path separators.');
604 }
605
607 }
isValidAttachmentPoolFilename(string $filename)

References $filename.

◆ getAbsoluteAttachmentPoolPathPrefix()

ilFileDataMail::getAbsoluteAttachmentPoolPathPrefix ( )

Definition at line 92 of file class.ilFileDataMail.php.

92 : string
93 {
94 return $this->mail_path . '/' . $this->user_id . '_';
95 }

◆ getAssignedRidStrings()

ilFileDataMail::getAssignedRidStrings ( ResourceCollectionIdentification  $rcid)
private
Returns
list<string>

Definition at line 1394 of file class.ilFileDataMail.php.

1394 : array
1395 {
1396 if (!$this->collectionIsKnown($rcid)) {
1397 return [];
1398 }
1399
1400 return array_values(array_map(
1401 static fn(ResourceIdentification $identification): string => $identification->serialize(),
1402 $this->irss->collection()->get($rcid)->getResourceIdentifications()
1403 ));
1404 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

+ Here is the call graph for this function:

◆ getAttachmentListing()

ilFileDataMail::getAttachmentListing ( ResourceCollectionIdentification  $rcid)

Keyed by resource id.

Equal display titles must not collapse two download hashes.

Returns
array<string, array{md5: string, name: string, size: int, ctime: string}>

Definition at line 1480 of file class.ilFileDataMail.php.

1480 : array
1481 {
1482 $files = [];
1483 foreach ($this->getAssignedRidStrings($rcid) as $rid) {
1484 $resource_identification = $this->irss->manage()->find($rid);
1485 if ($resource_identification === null) {
1486 continue;
1487 }
1488
1489 $revision = $this->irss->manage()->getCurrentRevision($resource_identification);
1490 $info = $revision->getInformation();
1491 $file_title = $info->getTitle();
1492 $files[$resource_identification->serialize()] = [
1493 'md5' => $this->attachmentHash($resource_identification),
1494 'name' => $file_title,
1495 'size' => $info->getSize(),
1496 'ctime' => $info->getCreationDate()->format('Y-m-d H:i:s'),
1497 ];
1498 }
1499
1500 return $files;
1501 }
attachmentHash(ResourceIdentification $identification)
Unique per resource: equal file names in one collection must stay distinguishable.
getAssignedRidStrings(ResourceCollectionIdentification $rcid)
$info
Definition: entry_point.php:21

References $files, and $info.

Referenced by ilMailFolderGUI\getAttachmentHashes().

+ Here is the caller graph for this function:

◆ getAttachmentPathAndFilenameByMd5Hash()

ilFileDataMail::getAttachmentPathAndFilenameByMd5Hash ( string  $md5FileHash,
int  $mail_id 
)
Returns
array{path: string, filename: string, rcid?: ResourceCollectionIdentification, md5?: string} An array containing 'path' and 'filename' for the passed MD5 hash
Exceptions
OutOfBoundsException

Definition at line 101 of file class.ilFileDataMail.php.

101 : array
102 {
103 $rcid = $this->getRcidForMailOfUser($mail_id);
104 if ($rcid !== null) {
105 $resource_identification = $this->getResourceIdByHash($rcid, $md5FileHash);
106 if ($resource_identification === null) {
107 throw new OutOfBoundsException();
108 }
109 $info = $this->irss->manage()->getCurrentRevision($resource_identification)->getInformation();
110
111 return [
112 'path' => '',
113 'filename' => $info->getTitle(),
114 'rcid' => $rcid,
115 'md5' => $md5FileHash,
116 ];
117 }
118
119 $res = $this->db->queryF(
120 '
121 SELECT mail_attachment.path
122 FROM mail_attachment
123 INNER JOIN mail ON mail.mail_id = mail_attachment.mail_id
124 WHERE mail_attachment.mail_id = %s
125 AND mail.user_id = %s
126 ',
127 ['integer', 'integer'],
128 [$mail_id, $this->user_id]
129 );
130
131 if ($this->db->numRows($res) !== 1) {
132 throw new OutOfBoundsException();
133 }
134
135 $row = $this->db->fetchAssoc($res);
136
137 $relative_path = $row['path'];
138 $path = $this->getMailPath() . '/' . $row['path'];
139
141 foreach ($files as $file) {
142 if ($file['type'] === 'file' && md5($file['entry']) === $md5FileHash) {
143 return [
144 'path' => $this->getMailPath() . '/' . $relative_path . '/' . $file['entry'],
145 'filename' => $file['entry'],
146 ];
147 }
148 }
149
150 throw new OutOfBoundsException();
151 }
getRcidForMailOfUser(int $mail_id)
static getDir(string $a_dir, bool $a_rec=false, ?string $a_sub_dir="")
get directory

References $files, $info, ilFile\$path, $res, ilFileUtils\getDir(), getMailPath(), getRcidForMailOfUser(), and getResourceIdByHash().

+ Here is the call graph for this function:

◆ getAttachmentPathByMailId()

ilFileDataMail::getAttachmentPathByMailId ( int  $mail_id)
private

Definition at line 153 of file class.ilFileDataMail.php.

153 : string
154 {
155 $query = $this->db->query(
156 'SELECT path FROM mail_attachment WHERE mail_id = ' . $this->db->quote($mail_id, 'integer')
157 );
158
159 while ($row = $this->db->fetchObject($query)) {
160 return $row->path;
161 }
162
163 return '';
164 }

Referenced by hasLegacyAttachmentDirectory().

+ Here is the caller graph for this function:

◆ getAttachmentsTotalSizeLimit()

ilFileDataMail::getAttachmentsTotalSizeLimit ( )

Definition at line 77 of file class.ilFileDataMail.php.

77 : ?float
78 {
79 $max_size = $this->ilias->getSetting('mail_maxsize_attach', '');
80 if ($max_size === '') {
81 return null;
82 }
83
84 return (float) $this->ilias->getSetting('mail_maxsize_attach', '0') * 1024;
85 }

◆ getCollection()

ilFileDataMail::getCollection ( ResourceCollectionIdentification  $rcid)

Definition at line 1365 of file class.ilFileDataMail.php.

1366 {
1367 if (!$this->collectionIsKnown($rcid)) {
1368 throw new OutOfBoundsException(
1369 sprintf('Mail attachment collection "%s" does not exist.', $rcid->serialize())
1370 );
1371 }
1372
1373 $this->irss->preloadCollections([$rcid->serialize()]);
1374
1375 return $this->irss->collection()->get($rcid, $this->user_id);
1376 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

Referenced by addResourceToPool().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ getIrssMimeAttachments()

ilFileDataMail::getIrssMimeAttachments ( ResourceCollectionIdentification  $rcid)
Returns
list<array{rid: string, name: string}>

Definition at line 1586 of file class.ilFileDataMail.php.

1586 : array
1587 {
1588 $attachments = [];
1589 foreach ($this->getAssignedRidStrings($rcid) as $rid) {
1590 $resource_identification = $this->irss->manage()->find($rid);
1591 if ($resource_identification === null) {
1592 continue;
1593 }
1594
1595 $info = $this->irss->manage()->getCurrentRevision($resource_identification)->getInformation();
1596 $attachments[] = [
1597 'rid' => $rid,
1598 'name' => $info->getTitle(),
1599 ];
1600 }
1601
1602 return $attachments;
1603 }

References $info.

◆ getMailPath()

ilFileDataMail::getMailPath ( )

Definition at line 87 of file class.ilFileDataMail.php.

87 : string
88 {
89 return $this->mail_path;
90 }

References $mail_path.

Referenced by getAttachmentPathAndFilenameByMd5Hash().

+ Here is the caller graph for this function:

◆ getPoolResourcesInStage()

ilFileDataMail::getPoolResourcesInStage ( ResourceCollectionIdentification  $stage_rcid)
Returns
list<string> Resource ids of the pool files the compose stage contains a copy of

Definition at line 1310 of file class.ilFileDataMail.php.

1310 : array
1311 {
1312 $stage_hashes = [];
1313 foreach ($this->getRidsFromCollection($stage_rcid) as $rid_string) {
1314 $identification = $this->irss->manage()->find($rid_string);
1315 if ($identification !== null) {
1316 $stage_hashes[$this->poolResourceHash($identification)] = true;
1317 }
1318 }
1319
1320 $pool_resources = [];
1321 foreach ($this->getUserPoolResources() as $pool_resource) {
1322 if (isset($stage_hashes[$this->poolResourceHash($pool_resource)])) {
1323 $pool_resources[] = $pool_resource->serialize();
1324 }
1325 }
1326
1327 return $pool_resources;
1328 }
getRidsFromCollection(ResourceCollectionIdentification $rcid)

◆ getRcidForMail()

ilFileDataMail::getRcidForMail ( int  $mail_id)

Definition at line 689 of file class.ilFileDataMail.php.

690 {
691 $res = $this->db->queryF(
692 'SELECT rcid FROM mail_attachment WHERE mail_id = %s',
693 ['integer'],
694 [$mail_id]
695 );
696
697 if ($this->db->numRows($res) !== 1) {
698 return null;
699 }
700
701 $row = $this->db->fetchAssoc($res);
702 $rcid = (string) ($row['rcid'] ?? '');
703 if ($rcid === '' || $rcid === '-') {
704 return null;
705 }
706
707 return new ResourceCollectionIdentification($rcid);
708 }

References $res.

◆ getRcidForMailOfUser()

ilFileDataMail::getRcidForMailOfUser ( int  $mail_id)
private

Definition at line 674 of file class.ilFileDataMail.php.

675 {
676 $res = $this->db->queryF(
677 'SELECT mail_attachment.rcid FROM mail_attachment
678 INNER JOIN mail ON mail.mail_id = mail_attachment.mail_id
679 WHERE mail_attachment.mail_id = %s AND mail.user_id = %s',
681 [$mail_id, $this->user_id]
682 );
683 $row = $this->db->fetchAssoc($res);
684 $rcid = is_array($row) ? (string) ($row['rcid'] ?? '') : '';
685
686 return $rcid !== '' && $rcid !== '-' ? new ResourceCollectionIdentification($rcid) : null;
687 }

References $res, and ilDBConstants\T_INTEGER.

Referenced by getAttachmentPathAndFilenameByMd5Hash().

+ Here is the caller graph for this function:

◆ getResourceIdByHash()

ilFileDataMail::getResourceIdByHash ( ResourceCollectionIdentification  $rcid,
string  $hash 
)

Definition at line 1411 of file class.ilFileDataMail.php.

1415 if (!$this->collectionIsKnown($rcid)) {
1416 return null;
1417 }
1418
1419 // Mails whose column still lists legacy filenames address their files by the hashed name (revision title)
1420 $title_match = null;
1421 foreach ($this->getAssignedRidStrings($rcid) as $rid) {
1422 $resource_identification = $this->irss->manage()->find($rid);
1423 if ($resource_identification === null) {
1424 continue;
1425 }
1426
1427 if ($this->attachmentHash($resource_identification) === $hash) {
1428 return $resource_identification;
1429 }
1430
1431 if ($title_match === null
1432 && $this->irss->manage()->getCurrentRevision($resource_identification)->getTitle() === $hash) {
1433 $title_match = $resource_identification;
1434 }
1435 }
1436
1437 return $title_match;
1438 }

Referenced by getAttachmentPathAndFilenameByMd5Hash().

+ Here is the caller graph for this function:

◆ getRidsFromCollection()

ilFileDataMail::getRidsFromCollection ( ResourceCollectionIdentification  $rcid)
Returns
list<string>

Definition at line 1463 of file class.ilFileDataMail.php.

1463 : array
1464 {
1465 $rids = [];
1466 foreach ($this->getAssignedRidStrings($rcid) as $rid) {
1467 if ($this->irss->manage()->find($rid) !== null) {
1468 $rids[] = $rid;
1469 }
1470 }
1471
1472 return $rids;
1473 }

◆ getStakeholder()

ilFileDataMail::getStakeholder ( )

Definition at line 997 of file class.ilFileDataMail.php.

998 {
999 return $this->stakeholder;
1000 }
readonly ilMailAttachmentStakeholder $stakeholder

◆ getUploadLimit()

ilFileDataMail::getUploadLimit ( )

Definition at line 72 of file class.ilFileDataMail.php.

72 : int
73 {
75 }

References $mail_max_upload_file_size.

◆ getUserPoolFilesData()

ilFileDataMail::getUserPoolFilesData ( )
Returns
list<array{rid: string, name: string, size: int, ctime: int, md5: string}>

Definition at line 322 of file class.ilFileDataMail.php.

322 : array
323 {
324 $files = [];
325
326 $pool_rcid = $this->resolveUserPoolRcid();
327 if ($pool_rcid !== null) {
328 foreach ($this->iteratePoolResourceIdentifications($pool_rcid) as $resource_identification) {
329 $revision = $this->irss->manage()->getCurrentRevision($resource_identification);
330 $info = $revision->getInformation();
331 $files[] = [
332 'rid' => $resource_identification->serialize(),
333 'name' => $info->getTitle(),
334 'size' => $info->getSize(),
335 'ctime' => $info->getCreationDate()->getTimestamp(),
336 'md5' => $revision->getTitle(),
337 ];
338 }
339 }
340
341 foreach ($this->getUnsentFiles() as $file) {
342 $files[] = [
343 'rid' => self::LEGACY_POOL_ITEM_PREFIX . $file['name'],
344 'name' => $file['name'],
345 'size' => (int) $file['size'],
346 'ctime' => (int) $file['ctime'],
347 'md5' => md5($file['name']),
348 ];
349 }
350
351 return $files;
352 }
iteratePoolResourceIdentifications(ResourceCollectionIdentification $pool_rcid)

References $files, $info, and ILIAS\Repository\int().

+ Here is the call graph for this function:

◆ getUserPoolRcid()

ilFileDataMail::getUserPoolRcid ( )

Definition at line 250 of file class.ilFileDataMail.php.

251 {
252 $pool_rcid = $this->resolveUserPoolRcid();
253 if ($pool_rcid === null) {
254 throw new RuntimeException('Mail attachment pool does not exist.');
255 }
256
257 return $pool_rcid;
258 }

References resolveUserPoolRcid().

+ Here is the call graph for this function:

◆ getUserPoolResources()

ilFileDataMail::getUserPoolResources ( )
private
Returns
list<ResourceIdentification>

Definition at line 1333 of file class.ilFileDataMail.php.

1333 : array
1334 {
1335 $pool_rcid = $this->resolveUserPoolRcid();
1336 if ($pool_rcid === null) {
1337 return [];
1338 }
1339
1340 return iterator_to_array($this->iteratePoolResourceIdentifications($pool_rcid), false);
1341 }

◆ hasLegacyAttachmentDirectory()

ilFileDataMail::hasLegacyAttachmentDirectory ( int  $mail_id)

Definition at line 166 of file class.ilFileDataMail.php.

166 : bool
167 {
168 return $this->getAttachmentPathByMailId($mail_id) !== '';
169 }

References getAttachmentPathByMailId().

+ Here is the call graph for this function:

◆ initAttachmentMaxUploadSize()

ilFileDataMail::initAttachmentMaxUploadSize ( )
protected
Todo:
mjansen: Unfortunately we cannot reuse the implementation of ilFileInputGUI

Definition at line 764 of file class.ilFileDataMail.php.

764 : void
765 {
768 // Copy of ilFileInputGUI: begin
769 // get the value for the maximal uploadable filesize from the php.ini (if available)
770 $umf = ini_get('upload_max_filesize');
771 // get the value for the maximal post data from the php.ini (if available)
772 $pms = ini_get('post_max_size');
773
774 // convert from short-string representation to "real" bytes
775 $multiplier_a = ['K' => 1024, 'M' => 1024 * 1024, 'G' => 1024 * 1024 * 1024];
776
777 $umf_parts = preg_split(
778 "/(\d+)([K|G|M])/",
779 (string) $umf,
780 -1,
781 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
782 );
783 $pms_parts = preg_split(
784 "/(\d+)([K|G|M])/",
785 (string) $pms,
786 -1,
787 PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY
788 );
789
790 if ((is_countable($umf_parts) ? count($umf_parts) : 0) === 2) {
791 $umf = (float) $umf_parts[0] * $multiplier_a[$umf_parts[1]];
792 }
793 if ((is_countable($pms_parts) ? count($pms_parts) : 0) === 2) {
794 $pms = (float) $pms_parts[0] * $multiplier_a[$pms_parts[1]];
795 }
796
797 // use the smaller one as limit
798 $max_filesize = min($umf, $pms);
799
800 if (!$max_filesize) {
801 $max_filesize = max($umf, $pms);
802 }
803
804 $this->mail_max_upload_file_size = (int) $max_filesize;
805 }

References ILIAS\Repository\int().

Referenced by __construct().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ isCollectionExclusivelyOwnedByMail()

ilFileDataMail::isCollectionExclusivelyOwnedByMail ( ResourceCollectionIdentification  $rcid)

True if the collection can be handed over to delivered mails without copying it: it is Mail-owned and nobody references it.

Definition at line 560 of file class.ilFileDataMail.php.

560 : bool
561 {
562 if ($this->isCollectionReferenced($rcid) || !$this->collectionIsKnown($rcid)) {
563 return false;
564 }
565
566 $rid_strings = $this->getRidsFromCollection($rcid);
567 if ($rid_strings === []) {
568 return false;
569 }
570
571 foreach ($rid_strings as $rid_string) {
572 $resource_identification = $this->irss->manage()->find($rid_string);
573 if ($resource_identification === null
574 || !$this->resourceHasOnlyMailStakeholder($resource_identification)) {
575 return false;
576 }
577 }
578
579 return true;
580 }
isCollectionReferenced(ResourceCollectionIdentification $rcid)
A Mail collection is referenced as long as a mail (sent, received, draft, outbox),...
resourceHasOnlyMailStakeholder(ResourceIdentification $rid)

◆ isCollectionReferenced()

ilFileDataMail::isCollectionReferenced ( ResourceCollectionIdentification  $rcid)

A Mail collection is referenced as long as a mail (sent, received, draft, outbox), a compose stage or a user's attachment pool points to it.

Definition at line 491 of file class.ilFileDataMail.php.

491 : bool
492 {
493 $serialized = $rcid->serialize();
494
495 $this->db->setLimit(1, 0);
496 $res = $this->db->queryF(
497 'SELECT 1 FROM mail_attachment WHERE rcid = %s',
499 [$serialized]
500 );
501 if ($this->db->numRows($res) > 0) {
502 return true;
503 }
504
505 $this->db->setLimit(1, 0);
506 $res = $this->db->queryF(
507 'SELECT 1 FROM mail_saved WHERE attachments = %s',
509 [$serialized]
510 );
511 if ($this->db->numRows($res) > 0) {
512 return true;
513 }
514
515 $res = $this->db->queryF(
516 'SELECT value FROM usr_pref WHERE usr_id = %s AND keyword = %s',
518 [$this->user_id, self::POOL_RCID_PREF_KEY]
519 );
520 $row = $this->db->fetchAssoc($res);
521
522 return is_array($row) && (string) $row['value'] === $serialized;
523 }

References $res, ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TEXT.

+ Here is the call graph for this function:

◆ isInUserPool()

ilFileDataMail::isInUserPool ( ResourceIdentification  $identification)

Definition at line 412 of file class.ilFileDataMail.php.

412 : bool
413 {
414 return $this->collectionContainsResource($this->resolveUserPoolRcid(), $identification);
415 }

◆ isLegacyPoolItemIdentifier()

ilFileDataMail::isLegacyPoolItemIdentifier ( string  $identifier)

Definition at line 354 of file class.ilFileDataMail.php.

354 : bool
355 {
356 return str_starts_with($identifier, self::LEGACY_POOL_ITEM_PREFIX);
357 }

◆ isValidAttachmentPoolFilename()

ilFileDataMail::isValidAttachmentPoolFilename ( string  $filename)
private

Definition at line 609 of file class.ilFileDataMail.php.

609 : bool
610 {
611 return $filename !== '' &&
612 !str_contains($filename, "\0") &&
613 !str_contains($filename, '/') &&
614 !str_contains($filename, '\\');
615 }

References $filename.

◆ iteratePoolResourceIdentifications()

ilFileDataMail::iteratePoolResourceIdentifications ( ResourceCollectionIdentification  $pool_rcid)
private
Returns
\Generator<int, ResourceIdentification>

Definition at line 309 of file class.ilFileDataMail.php.

309 : Generator
310 {
311 foreach ($this->getAssignedRidStrings($pool_rcid) as $rid_string) {
312 $resource_identification = $this->irss->manage()->find($rid_string);
313 if ($resource_identification !== null) {
314 yield $resource_identification;
315 }
316 }
317 }

◆ legacyPoolFilenameFromIdentifier()

ilFileDataMail::legacyPoolFilenameFromIdentifier ( string  $identifier)

Definition at line 359 of file class.ilFileDataMail.php.

359 : string
360 {
361 return substr($identifier, strlen(self::LEGACY_POOL_ITEM_PREFIX));
362 }

◆ loadPoolCollectionForMutation()

ilFileDataMail::loadPoolCollectionForMutation ( ?ResourceCollectionIdentification  $pool_rcid)
private

Definition at line 1378 of file class.ilFileDataMail.php.

1379 {
1380 if ($pool_rcid !== null && $this->collectionIsKnown($pool_rcid)) {
1381 $this->irss->preloadCollections([$pool_rcid->serialize()]);
1382
1383 return $this->irss->collection()->get($pool_rcid, $this->user_id);
1384 }
1385
1386 $collection_id = $this->irss->collection()->id(null, $this->user_id);
1387
1388 return $this->irss->collection()->get($collection_id, $this->user_id);
1389 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

+ Here is the call graph for this function:

◆ migrateLegacyPoolAttachments()

ilFileDataMail::migrateLegacyPoolAttachments ( MailAttachments  $attachments)

Definition at line 1118 of file class.ilFileDataMail.php.

1119 {
1120 if (!$attachments->isLegacy()) {
1121 return $attachments;
1122 }
1123
1124 if (!$this->checkFilesExist($attachments->legacyFilenames())) {
1125 return null;
1126 }
1127
1128 $rcid = $this->createCollectionFromPoolFilenames($attachments->legacyFilenames());
1129
1130 return $rcid !== null ? MailAttachments::fromIrss($rcid) : null;
1131 }
checkFilesExist(array $a_files)
createCollectionFromPoolFilenames(array $filenames)

References ILIAS\Mail\Attachments\MailAttachments\isLegacy(), and ILIAS\Mail\Attachments\MailAttachments\legacyFilenames().

+ Here is the call graph for this function:

◆ migrateLegacyPoolFilenameToResource()

ilFileDataMail::migrateLegacyPoolFilenameToResource ( string  $filename)

Definition at line 364 of file class.ilFileDataMail.php.

365 {
367 if (!is_file($path)) {
368 return null;
369 }
370
371 $rid = $this->streamFromPath($path, md5($filename));
372 $this->applyResourceFileName($rid, $filename);
373 try {
374 $rid = $this->addResourceToPool($rid);
375 } catch (RuntimeException) {
376 return null;
377 }
378
379 $this->unlinkFile($filename);
380
381 return $rid;
382 }
addResourceToPool(ResourceIdentification $rid)
Adds a resource to the user's pool.
unlinkFile(string $a_filename)

References $filename.

◆ persistUserPoolRcid()

ilFileDataMail::persistUserPoolRcid ( ResourceCollectionIdentification  $rcid)
private

Definition at line 473 of file class.ilFileDataMail.php.

473 : void
474 {
475 $this->db->replace(
476 'usr_pref',
477 [
478 'usr_id' => [ilDBConstants::T_INTEGER, $this->user_id],
479 'keyword' => [ilDBConstants::T_TEXT, self::POOL_RCID_PREF_KEY],
480 ],
481 [
482 'value' => [ilDBConstants::T_TEXT, $rcid->serialize()],
483 ]
484 );
485 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TEXT.

Referenced by addResourceToPool().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ poolResourceHash()

ilFileDataMail::poolResourceHash ( ResourceIdentification  $rid)

Definition at line 468 of file class.ilFileDataMail.php.

468 : string
469 {
470 return $this->irss->manage()->getCurrentRevision($rid)->getTitle();
471 }

Referenced by addResourceToPool().

+ Here is the caller graph for this function:

◆ releaseCollectionIfUnreferenced()

ilFileDataMail::releaseCollectionIfUnreferenced ( ResourceCollectionIdentification  $rcid)

Removes a Mail collection nobody references anymore, together with its resources.

Collections containing resources of other components are never touched.

Definition at line 529 of file class.ilFileDataMail.php.

529 : void
530 {
531 $serialized = $rcid->serialize();
532 if ($serialized === '' || $serialized === '-') {
533 return;
534 }
535
536 if ($this->isCollectionReferenced($rcid) || !$this->collectionIsKnown($rcid)) {
537 return;
538 }
539
540 foreach ($this->getRidsFromCollection($rcid) as $rid_string) {
541 $resource_identification = $this->irss->manage()->find($rid_string);
542 if ($resource_identification !== null
543 && !$this->resourceHasOnlyMailStakeholder($resource_identification)) {
544 return;
545 }
546 }
547
548 $this->removeCollection($rcid, true);
549 }
removeCollection(ResourceCollectionIdentification $rcid, bool $delete_resources=false)
Removes the collection.

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

+ Here is the call graph for this function:

◆ releaseSourceCollectionAfterDelivery()

ilFileDataMail::releaseSourceCollectionAfterDelivery ( ResourceCollectionIdentification  $rcid)

Drops the source collection after it has been delivered.

Foreign collections (Exercise, Test, …), the user pool and collections still referenced by mails or a compose stage stay untouched.

Definition at line 1545 of file class.ilFileDataMail.php.

1545 : void
1546 {
1547 $this->releaseCollectionIfUnreferenced($rcid);
1548 }

◆ removeCollection()

ilFileDataMail::removeCollection ( ResourceCollectionIdentification  $rcid,
bool  $delete_resources = false 
)

Removes the collection.

Resources are only deleted if explicitly requested; prefer releaseCollectionIfUnreferenced() which respects references of mails, stage and pool.

Definition at line 1527 of file class.ilFileDataMail.php.

1527 : void
1528 {
1529 if (!$this->irss->collection()->exists($rcid->serialize())) {
1530 return;
1531 }
1532
1533 $this->irss->collection()->remove(
1534 $rcid,
1535 $this->stakeholder,
1536 $delete_resources
1537 );
1538 }

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize().

+ Here is the call graph for this function:

◆ removeFromPool()

ilFileDataMail::removeFromPool ( ResourceIdentification  $rid)

Definition at line 450 of file class.ilFileDataMail.php.

450 : void
451 {
452 $pool_rcid = $this->resolveUserPoolRcid();
453 if ($pool_rcid === null) {
454 return;
455 }
456
457 $collection = $this->getCollection($pool_rcid);
458 if (!$collection->isIn($rid)) {
459 return;
460 }
461
462 $collection->remove($rid);
463 $this->irss->collection()->store($collection);
464
465 $this->deleteResource($rid);
466 }

Referenced by addResourceToPool().

+ Here is the caller graph for this function:

◆ removeFromStage()

ilFileDataMail::removeFromStage ( ResourceIdentification  $identification)

Definition at line 1027 of file class.ilFileDataMail.php.

1027 : bool
1028 {
1029 $stage_rcid = $this->resolveStageRcid();
1030 if (!$this->collectionContainsResource($stage_rcid, $identification)) {
1031 return false;
1032 }
1033
1034 $collection = $this->getCollection($stage_rcid);
1035 $collection->remove($identification);
1036 $this->irss->collection()->store($collection);
1037 $this->deleteResource($identification);
1038
1039 return true;
1040 }

◆ replaceMailAttachmentCollection()

ilFileDataMail::replaceMailAttachmentCollection ( int  $mail_id,
?ResourceCollectionIdentification  $rcid 
)

Points a mail (draft, outbox) to the passed collection (or to none).

A previously referenced collection is released if nothing else references it anymore.

Definition at line 648 of file class.ilFileDataMail.php.

648 : void
649 {
650 if ($this->hasLegacyAttachmentDirectory($mail_id)) {
651 return;
652 }
653
654 $previous_rcid = $this->getRcidForMail($mail_id);
655 if ($previous_rcid !== null && $rcid !== null && $previous_rcid->serialize() === $rcid->serialize()) {
656 return;
657 }
658
659 $this->db->manipulateF(
660 'DELETE FROM mail_attachment WHERE mail_id = %s AND (path IS NULL OR path = %s)',
662 [$mail_id, '']
663 );
664
665 if ($rcid !== null) {
666 $this->assignAttachmentsToCollection($mail_id, $rcid);
667 }
668
669 if ($previous_rcid !== null) {
670 $this->releaseCollectionIfUnreferenced($previous_rcid);
671 }
672 }
assignAttachmentsToCollection(int $mail_id, ResourceCollectionIdentification $rcid)

References ILIAS\ResourceStorage\Identification\AbstractIdentification\serialize(), ilDBConstants\T_INTEGER, and ilDBConstants\T_TEXT.

+ Here is the call graph for this function:

◆ resolvePoolIdentifiersToResources()

ilFileDataMail::resolvePoolIdentifiersToResources ( array  $identifiers)
Parameters
list<string>$identifiers
Returns
list<ResourceIdentification>

Definition at line 388 of file class.ilFileDataMail.php.

388 : array
389 {
390 $resource_identifications = [];
391
392 foreach ($identifiers as $identifier) {
393 if ($this->isLegacyPoolItemIdentifier($identifier)) {
394 $resource_identification = $this->migrateLegacyPoolFilenameToResource(
395 $this->legacyPoolFilenameFromIdentifier($identifier)
396 );
397 } else {
398 $resource_identification = $this->irss->manage()->find($identifier);
399 if ($resource_identification !== null && !$this->isInUserPool($resource_identification)) {
400 $resource_identification = null;
401 }
402 }
403
404 if ($resource_identification !== null) {
405 $resource_identifications[] = $resource_identification;
406 }
407 }
408
409 return $resource_identifications;
410 }
isLegacyPoolItemIdentifier(string $identifier)
legacyPoolFilenameFromIdentifier(string $identifier)
migrateLegacyPoolFilenameToResource(string $filename)
isInUserPool(ResourceIdentification $identification)

◆ resolveStageRcid()

ilFileDataMail::resolveStageRcid ( )
private

Definition at line 275 of file class.ilFileDataMail.php.

276 {
277 $res = $this->db->queryF(
278 'SELECT attachments FROM mail_saved WHERE user_id = %s',
280 [$this->user_id]
281 );
282 $row = $this->db->fetchAssoc($res);
283 if (!is_array($row)) {
284 return null;
285 }
286
287 $stage = MailAttachments::fromDb(is_string($row['attachments'] ?? null) ? $row['attachments'] : null);
288 if ($stage === null || !$stage->isIrss()) {
289 return null;
290 }
291
292 return $stage->rcid();
293 }

References $res, and ilDBConstants\T_INTEGER.

◆ resolveUserPoolRcid()

ilFileDataMail::resolveUserPoolRcid ( )
private

Definition at line 260 of file class.ilFileDataMail.php.

261 {
262 $pref = ilObjUser::_lookupPref($this->user_id, self::POOL_RCID_PREF_KEY);
263 if (!is_string($pref) || $pref === '') {
264 return null;
265 }
266
267 $rcid = new ResourceCollectionIdentification($pref);
268 if (!$this->collectionIsKnown($rcid)) {
269 return null;
270 }
271
272 return $rcid;
273 }
static _lookupPref(int $a_usr_id, string $a_keyword)

References ilObjUser\_lookupPref(), and collectionIsKnown().

Referenced by addResourceToPool(), and getUserPoolRcid().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ resourceHasOnlyMailStakeholder()

ilFileDataMail::resourceHasOnlyMailStakeholder ( ResourceIdentification  $rid)
private

Definition at line 1570 of file class.ilFileDataMail.php.

1570 : bool
1571 {
1572 $has_mail = false;
1573 foreach ($this->irss->manage()->getResource($rid)->getStakeholders() as $stakeholder) {
1574 if ($stakeholder->getId() !== $this->stakeholder->getId()) {
1575 return false;
1576 }
1577 $has_mail = true;
1578 }
1579
1580 return $has_mail;
1581 }

◆ resourceIdByHashInCollection()

ilFileDataMail::resourceIdByHashInCollection ( ResourceCollection  $collection,
string  $hash 
)
private

Definition at line 1448 of file class.ilFileDataMail.php.

1449 {
1450 foreach ($collection->getResourceIdentifications() as $resource_identification) {
1451 $revision = $this->irss->manage()->getCurrentRevision($resource_identification);
1452 if ($revision->getTitle() === $hash) {
1453 return $resource_identification;
1454 }
1455 }
1456
1457 return null;
1458 }

References ILIAS\ResourceStorage\Collection\ResourceCollection\getResourceIdentifications().

Referenced by addResourceToPool().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ restrictStageTo()

ilFileDataMail::restrictStageTo ( array  $rid_strings)

Removes all files from the compose stage which are not part of the submitted form.

Parameters
list<string>$rid_strings

Definition at line 1047 of file class.ilFileDataMail.php.

1048 {
1049 $stage_rcid = $this->resolveStageRcid();
1050 if ($stage_rcid === null || !$this->collectionIsKnown($stage_rcid)) {
1051 return null;
1052 }
1053
1054 $kept = array_flip($rid_strings);
1055 $collection = $this->getCollection($stage_rcid);
1056 $removed = [];
1057 foreach ($collection->getResourceIdentifications() as $identification) {
1058 if (!isset($kept[$identification->serialize()])) {
1059 $collection->remove($identification);
1060 $removed[] = $identification;
1061 }
1062 }
1063
1064 if ($removed !== []) {
1065 $this->irss->collection()->store($collection);
1066 foreach ($removed as $identification) {
1067 $this->deleteResource($identification);
1068 }
1069 }
1070
1071 return $collection->count() > 0 ? $collection->getIdentification() : null;
1072 }

◆ streamFromPath()

ilFileDataMail::streamFromPath ( string  $absolute_path,
?string  $revision_title = null 
)

Definition at line 1074 of file class.ilFileDataMail.php.

1075 {
1076 $stream = Streams::ofResource(fopen($absolute_path, 'rb'));
1077
1078 return $this->irss->manage()->stream(
1079 $stream,
1080 $this->stakeholder,
1081 $revision_title ?? md5(basename($absolute_path))
1082 );
1083 }

◆ unlinkFile()

ilFileDataMail::unlinkFile ( string  $a_filename)

Definition at line 582 of file class.ilFileDataMail.php.

582 : bool
583 {
584 if (!$this->isValidAttachmentPoolFilename($a_filename)) {
585 return false;
586 }
587
589 if (is_file($path)) {
590 return unlink($path);
591 }
592
593 return false;
594 }

◆ uploadToIrss()

ilFileDataMail::uploadToIrss ( UploadResult  $result)

Definition at line 1085 of file class.ilFileDataMail.php.

1086 {
1087 return $this->irss->manage()->upload(
1088 $result,
1089 $this->stakeholder,
1090 md5($result->getName())
1091 );
1092 }

References ILIAS\FileUpload\DTO\UploadResult\getName().

Referenced by uploadToPool().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ uploadToPool()

ilFileDataMail::uploadToPool ( UploadResult  $result)

Definition at line 213 of file class.ilFileDataMail.php.

214 {
215 $rid = $this->uploadToIrss($result);
216
217 return $this->addResourceToPool($rid);
218 }
uploadToIrss(UploadResult $result)

References addResourceToPool(), and uploadToIrss().

+ Here is the call graph for this function:

Field Documentation

◆ $db

ilDBInterface ilFileDataMail::$db
protected

Definition at line 46 of file class.ilFileDataMail.php.

◆ $ilias

ILIAS ilFileDataMail::$ilias
protected

Definition at line 47 of file class.ilFileDataMail.php.

◆ $irss

readonly Services ilFileDataMail::$irss
private

Definition at line 48 of file class.ilFileDataMail.php.

◆ $mail_max_upload_file_size

int ilFileDataMail::$mail_max_upload_file_size
protected

Definition at line 43 of file class.ilFileDataMail.php.

Referenced by getUploadLimit().

◆ $mail_path

string ilFileDataMail::$mail_path

Definition at line 42 of file class.ilFileDataMail.php.

Referenced by getMailPath().

◆ $stakeholder

readonly ilMailAttachmentStakeholder ilFileDataMail::$stakeholder
private

Definition at line 49 of file class.ilFileDataMail.php.

◆ $storage_directory

Filesystem ilFileDataMail::$storage_directory
protected

Definition at line 45 of file class.ilFileDataMail.php.

◆ $tmp_directory

Filesystem ilFileDataMail::$tmp_directory
protected

Definition at line 44 of file class.ilFileDataMail.php.

◆ LEGACY_POOL_ITEM_PREFIX

const string ilFileDataMail::LEGACY_POOL_ITEM_PREFIX = 'legacy:'

Definition at line 40 of file class.ilFileDataMail.php.

◆ POOL_RCID_PREF_KEY

const string ilFileDataMail::POOL_RCID_PREF_KEY = 'mail_attachment_pool_rcid'

The documentation for this class was generated from the following file: