Esempio n. 1
0
        // Note attachments are currently saved into the authors file directory
        private void SaveAttachments(int contentId)
        {
            var fileManager = FileManager.Instance;
            var folderManager = FolderManager.Instance;
            var adb = new Data.AttachController();

            var userFolder = folderManager.GetUserFolder(UserInfo);

            const string uploadFolderName = "activeforums_Upload";
            const string attachmentFolderName = "activeforums_Attach";
            const string fileNameTemplate = "__{0}__{1}__{2}";

            var attachmentFolder = folderManager.GetFolder(PortalId, attachmentFolderName) ?? folderManager.AddFolder(PortalId, attachmentFolderName);

            // Read the attachment list sent in the hidden field as json
            var attachmentsJson = hidAttachments.Value;
            var serializer = new DataContractJsonSerializer(typeof (List<ClientAttachment>));
            var ms = new MemoryStream(Encoding.UTF8.GetBytes(attachmentsJson));
            var attachmentsNew = (List<ClientAttachment>)serializer.ReadObject(ms);
            ms.Close();

            // Read the list of existing attachments for the content.  Must do this before saving any of the new attachments!
            // Ignore any legacy inline attachments
            var attachmentsOld = adb.ListForContent(contentId).Where(o => !o.AllowDownload.HasValue || o.AllowDownload.Value);

            // Save all of the new attachments
            foreach(var attachment in attachmentsNew)
            {
                // Don't need to do anything with existing attachments
                if(attachment.AttachmentId.HasValue && attachment.AttachmentId.Value > 0)
                    continue;

                IFileInfo file = null;

                var fileId = attachment.FileId.GetValueOrDefault();
                if(fileId > 0 && userFolder != null)
                {
                    // Make sure that the file exists and it actually belongs to the user who is trying to attach it
                    file = fileManager.GetFile(fileId);
                    if(file == null || file.FolderId != userFolder.FolderID) continue;
                }
                else if(!string.IsNullOrWhiteSpace(attachment.UploadId) && !string.IsNullOrWhiteSpace(attachment.FileName))
                {
                    if (!Regex.IsMatch(attachment.UploadId, @"^[\w\-. ]+$")) // Check for shenanigans.
                        continue;

                    var uploadFilePath = PathUtils.Instance.GetPhysicalPath(PortalId, uploadFolderName + "/" + attachment.UploadId);

                    if (!File.Exists(uploadFilePath))
                        continue;

                    // Store the files with a filename format that prevents overwrites.
                    var index = 0;
                    var fileName = string.Format(fileNameTemplate, contentId, index, Regex.Replace(attachment.FileName, @"[^\w\-. ]+", string.Empty));
                    while(fileManager.FileExists(attachmentFolder, fileName))
                    {
                        index++;
                        fileName = string.Format(fileNameTemplate, contentId, index, Regex.Replace(attachment.FileName, @"[^\w\-. ]+", string.Empty));
                    }

                    // Copy the file into the attachment folder with the correct name.
                    using (var fileStream = new FileStream(uploadFilePath, FileMode.Open, FileAccess.Read))
                    {
                        file = fileManager.AddFile(attachmentFolder, fileName, fileStream);
                    }

                    File.Delete(uploadFilePath);
                }

                if(file == null)
                    continue;

                adb.Save(contentId, UserId, file.FileName, file.ContentType, file.Size, file.FileId);
            }

            // Remove any attachments that are no longer in the list of attachments
            var attachmentsToRemove = attachmentsOld.Where(a1 => attachmentsNew.All(a2 => a2.AttachmentId != a1.AttachmentId));
            foreach(var attachment in attachmentsToRemove)
            {
                adb.Delete(attachment.AttachmentId);

                var file = attachment.FileId.HasValue ? fileManager.GetFile(attachment.FileId.Value) : fileManager.GetFile(attachmentFolder, attachment.FileName);

                // Only delete the file if it exists in the attachment folder
                if(file != null && file.FolderId == attachmentFolder.FolderID)
                    fileManager.DeleteFile(file);
            }
        }
Esempio n. 2
0
        private void PrepareAttachments(int? contentId = null)
        {
            // Handle the case where we don't yet have a topic id (new posts)
            if(!contentId.HasValue || contentId.Value <= 0)
            {
                hidAttachments.Value = "[]"; // JSON for an empty array
                return;
            }

            var adb = new Data.AttachController();
            var attachments = adb.ListForContent(contentId.Value);

            var clientAttachments = attachments.Select(attachment => new ClientAttachment
            {
                AttachmentId = attachment.AttachmentId,
                ContentType = attachment.ContentType,
                FileId = attachment.FileId,
                FileName = Regex.Replace(attachment.FileName.TextOrEmpty(), @"^__\d+__\d+__", string.Empty), // Remove our unique file prefix before sending to the client.
                FileSize = attachment.FileSize
            }).ToList();

            var serializer = new DataContractJsonSerializer(typeof(List<ClientAttachment>));

            using(var ms = new MemoryStream())
            {
                serializer.WriteObject(ms, clientAttachments);
                ms.Seek(0, 0);
                using(var sr = new StreamReader(ms, Encoding.UTF8))
                {
                    hidAttachments.Value = sr.ReadToEnd();
                }
            }
        }