private async Task <(MediaFile Copy, bool IsDupe)> InternalCopyFile( MediaFile file, MediaPathData destPathData, bool copyData, DuplicateEntryHandling dupeEntryHandling, Func <Task <MediaFile> > dupeFileSelector, Func <MediaPathData, Task> uniqueFileNameChecker) { // Find dupe and handle var isDupe = false; var dupe = await dupeFileSelector(); if (dupe != null) { switch (dupeEntryHandling) { case DuplicateEntryHandling.Skip: await uniqueFileNameChecker(destPathData); return(dupe, true); case DuplicateEntryHandling.ThrowError: var fullPath = destPathData.FullPath; await uniqueFileNameChecker(destPathData); throw _exceptionFactory.DuplicateFile(fullPath, ConvertMediaFile(dupe), destPathData.FullPath); case DuplicateEntryHandling.Rename: await uniqueFileNameChecker(destPathData); dupe = null; break; case DuplicateEntryHandling.Overwrite: if (file.FolderId == destPathData.Folder.Id) { throw new IOException(T("Admin.Media.Exception.Overwrite")); } break; } } isDupe = dupe != null; var copy = dupe ?? new MediaFile(); // Simple clone MapMediaFile(file, copy); // Set folder id copy.FolderId = destPathData.Folder.Id; // A copied file cannot stay in deleted state copy.Deleted = false; // Set name stuff if (!copy.Name.EqualsNoCase(destPathData.FileName)) { copy.Name = destPathData.FileName; copy.Extension = destPathData.Extension; copy.MimeType = destPathData.MimeType; } // Save to DB if (isDupe) { _db.TryChangeState(copy, EntityState.Modified); } else { _db.MediaFiles.Add(copy); } // Copy data: blob, alt, title etc. if (copyData) { await InternalCopyFileData(file, copy); } return(copy, isDupe); }
protected virtual async Task TrackSingleAsync(BaseEntity entity, int mediaFileId, string propertyName, MediaTrackOperation operation) { Guard.NotNull(entity, nameof(entity)); if (mediaFileId < 1 || entity.IsTransientRecord()) { return; } var file = await _db.MediaFiles.FindByIdAsync(mediaFileId); if (file != null) { var album = _folderService.FindAlbum(file)?.Value; if (album == null) { throw new InvalidOperationException(T("Admin.Media.Exception.TrackUnassignedFile")); } else if (!album.CanDetectTracks) { // No support for tracking on album level, so get outta here. return; } var track = new MediaTrack { EntityId = entity.Id, EntityName = entity.GetEntityName(), MediaFileId = mediaFileId, Property = propertyName, Album = album.Name }; if (operation == MediaTrackOperation.Track) { file.Tracks.Add(track); } else { var dbTrack = file.Tracks.FirstOrDefault(x => x == track); if (dbTrack != null) { file.Tracks.Remove(track); _db.TryChangeState(dbTrack, EfState.Deleted); } } if (file.Tracks.Count > 0) { // A file with tracks can NEVER be transient file.IsTransient = false; } else if (_makeFilesTransientWhenOrphaned) { // But an untracked file can OPTIONALLY be transient file.IsTransient = true; } await _db.SaveChangesAsync(); } }
public virtual async Task <CreateMessageResult> CreateMessageAsync(MessageContext messageContext, bool queue, params object[] modelParts) { Guard.NotNull(messageContext, nameof(messageContext)); modelParts ??= Array.Empty <object>(); // Handle TestMode if (messageContext.TestMode && modelParts.Length == 0) { modelParts = await GetTestModelsAsync(messageContext); } ValidateMessageContext(messageContext, ref modelParts); // Create and assign model. var model = messageContext.Model = new TemplateModel(); // Do not create message if the template does not exist, is not authorized or not active. if (messageContext.MessageTemplate == null) { return(new CreateMessageResult { Model = model, MessageContext = messageContext }); } // Add all global template model parts. await _modelProvider.AddGlobalModelPartsAsync(messageContext); // Add specific template models for passed parts. foreach (var part in modelParts) { if (model != null) { await _modelProvider.AddModelPartAsync(part, messageContext); } } // Give implementors the chance to customize the final template model. await _eventPublisher.PublishAsync(new MessageModelCreatedEvent(messageContext, model)); var messageTemplate = messageContext.MessageTemplate; var languageId = messageContext.Language.Id; // Render templates var to = RenderEmailAddress(messageTemplate.To, messageContext); var replyTo = RenderEmailAddress(messageTemplate.ReplyTo, messageContext, false); var bcc = RenderTemplate(messageTemplate.GetLocalized((x) => x.BccEmailAddresses, languageId), messageContext, false); var subject = RenderTemplate(messageTemplate.GetLocalized((x) => x.Subject, languageId), messageContext); ((dynamic)model).Email.Subject = subject; var body = RenderBodyTemplate(messageContext); // CSS inliner body = InlineCss(body, model); // Model tree var modelTree = _modelProvider.BuildModelTree(model); var modelTreeJson = JsonConvert.SerializeObject(modelTree, Formatting.None); if (modelTreeJson != messageTemplate.LastModelTree) { messageContext.MessageTemplate.LastModelTree = modelTreeJson; if (!messageTemplate.IsTransientRecord()) { _db.TryChangeState(messageContext.MessageTemplate, EntityState.Modified); await _db.SaveChangesAsync(); } } // Create queued email from template var qe = new QueuedEmail { Priority = 5, From = messageContext.SenderMailAddress ?? messageContext.EmailAccount.ToMailAddress(), To = to.ToString(), Bcc = bcc, ReplyTo = replyTo?.ToString(), Subject = subject, Body = body, CreatedOnUtc = DateTime.UtcNow, EmailAccountId = messageContext.EmailAccount.Id, SendManually = messageTemplate.SendManually }; // Create and add attachments (if any). await CreateAttachmentsAsync(qe, messageContext); if (queue) { // Put to queue. await QueueMessageAsync(messageContext, qe); } return(new CreateMessageResult { Email = qe, Model = model, MessageContext = messageContext }); }