using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Sarand.Net.Standard.Base.App; using Sarand.Net.Standard.Base.Bus; using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Dbas; using Sarand.Net.Standard.Base.Helpers; using Sarand.Net.Standard.Base.Utils; using Saxonite.Net.Core.Web.Admin.Models; using Saxonite.Net.Standard.Base.App; using Saxonite.Net.Standard.Base.Bus; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.IO; using System.Linq; using System.Threading.Tasks; namespace Saxonite.Net.Core.Web.Admin.Controllers { //======================================================================= // Controller: Organisation Images - Ajax //======================================================================= partial class OrganisationController { //------------------------------------------------------------------- private class OrganisationImagesData : OrganisationItemData { } private void PopulateOrganisationResponseImagesData(SaxOrganisation organisation, SaxItemAddress address, OrganisationImagesData data) { PopulateOrganisationResponseItemData(organisation, address, data); } //------------------------------------------------------------------- // Get Organisation Images ajax request. //------------------------------------------------------------------- private class AjaxResponse_OrganisationImages : AjaxResponse_Data { // Construction. public AjaxResponse_OrganisationImages(SaxModel_Admin model) : base(model) { } // Organisation details. public OrganisationImagesData organisation { get; } = new OrganisationImagesData(); // Reference data. public List ImageContentTypes { get; set; } } //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/GetImages")] [Route("Organisation/Ajax/GetItemImages")] public IActionResult Ajax_GetImages(Model_Organisation model) { String fn = GetType().Name + ".Ajax_GetImages"; String messageTitle = Localiser["caption.organisation"]; AjaxResponse_OrganisationImages responseData = new AjaxResponse_OrganisationImages(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Reference data - Image content types. responseData.ImageContentTypes = SaxItemImage.GetValidContentTypes(Sax.DataItemType.Organisation); // Identify item. SysId organisationId = model.OrganisationId.ToSysId(); if (!SysId.IsValid(organisationId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); // Retrieve item. SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null) { SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Organisation address. SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId()); disposableItems.Add(address); // Construct response. PopulateOrganisationResponseImagesData(organisation, address, responseData.organisation); // Complete response. responseData.Success = true; } return Json(responseData); } //------------------------------------------------------------------- // Account - Upload Contact Image. // Ref. http://www.binaryintellect.net/articles/474dc031-087f-4b81-b994-9ca2adb949d6.aspx //------------------------------------------------------------------- private class AjaxResponse_UploadOrganisationLogoImage : AjaxResponse_Data { // Construction. public AjaxResponse_UploadOrganisationLogoImage(SaxModel_Admin model) : base(model) { } // Uploaded image URL. public String ImageUrl { get; set; } // Upload message. public String UploadMsg { get; set; } } // Ajax request. [HttpPost] [Route("Organisation/Ajax/UploadLogo")] [Route("Organisation/Ajax/UploadLogoImage")] public IActionResult UploadOrganisationLogoImage(Model_Organisation model) { String fn = GetType().Name + ".UploadOrganisationLogoImage"; AjaxResponse_UploadOrganisationLogoImage responseData = new AjaxResponse_UploadOrganisationLogoImage(model); String messageTitle = Localiser["caption.organisation"]; // Validate session and referrer. if (!ValidReferer) return Forbid(); if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); RefreshModel(model); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Retrieve organisation. SysId organisationId = model.OrganisationId.ToSysId(); if (!SysId.IsValid(organisationId)) return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.specified"])); SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null) { SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Validate number of images. if (model.OrganisationLogoImage.IsEmpty()) { SaLogger.Warn(fn + " No image file supplied for upload"); return Json(responseData); } if (model.OrganisationLogoImage.Count != 1) { SaLogger.Warn(fn + " Invalid number of image files uploaded: " + model.OrganisationLogoImage.Count); return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.upload.image.single"])); } IFormFile file = model.OrganisationLogoImage[0]; // Image properties. byte[] imageData = null; using (MemoryStream fileStream = new MemoryStream()) { file.CopyTo(fileStream); imageData = fileStream.ToArray(); } // Validate the image. ImageUtils.ImageConfig imageConfig = ImageUtils.VerifyImageData(imageData); if (!imageConfig.ValidImage) return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.upload.image.invalid"])); // Validate mime type. if (!SaxItemImage.GetValidMimeTypes(Sax.DataItemType.UserAccount).Contains(imageConfig.MimeType)) return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.upload.image.invalid.mime"])); // Validate content type. if (StringUtil.IsEmpty(file.ContentType) || !SaxItemImage.GetValidContentTypes(Sax.DataItemType.UserAccount).ContainsCI(file.ContentType)) return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.upload.image.invalid.content.type"])); // Resize the image if required. if (!ImageUtils.ConstrainImage(imageConfig, Sax.Config.Organisation.Logo.WidthMax, Sax.Config.Organisation.Logo.HeightMax)) return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.upload.image.resize.failed"])); // Image belongs to the organisation. ItemId organisationItemId = organisation.GetItemId(); // Store uploaded image as 'Upload' Logo - awaiting confirmation that the details are to be saved. SaxItemImage itemImage = ItemDataMgr.GetItemImage(organisationItemId, Sax.ImageType.OrganisationLogo_Upload, SaxItemImage.StatusCat.Any); if (itemImage == null) itemImage = ItemDataMgr.CreateItemImage(organisationItemId, Sax.ImageType.OrganisationLogo_Upload); itemImage.Filename = file.FileName; itemImage.Mime = SacsContentTypeHelper.GetMimeTypeFromContentType(file.ContentType).ToString().ToLower(); itemImage.ContentType = file.ContentType; itemImage.ImageData = imageConfig.ImageData; itemImage.Width = imageConfig.Width; itemImage.Height = imageConfig.Height; itemImage.Status = SaxItemImage.DefaultStatus; if (!SysId.IsValid(itemImage.Id)) { if (!ItemDataMgr.InsertItemImage(itemImage, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert uploaded image - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.error.item.insert.failed"])); } } else { if (!ItemDataMgr.UpdateItemImage(itemImage, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update uploaded image - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetControlError("OrganisationLogoImage", Localiser["msg.error.item.insert.failed"])); } } // Return image url with response. responseData.ImageUrl = GetOrganisationLogoLink(organisation.Id, true); } // Complete response. responseData.SetNotification(messageTitle, "Image uploaded."); responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- // Store Organisation Images ajax request. //------------------------------------------------------------------- [HttpPost] [Route("Organisation/Ajax/StoreImages")] public IActionResult Ajax_StoreImages(Model_Organisation model) { String fn = GetType().Name + ".Ajax_StoreImages"; String messageTitle = Localiser["caption.organisation"]; AjaxResponse_OrganisationImages responseData = new AjaxResponse_OrganisationImages(model); // Validate session. if (!ValidUserSession) return GetAjaxResult_InvalidSession(responseData); // Record disposable items as they are created so all can be disposed when needed. using (DisposableCollection disposableItems = new DisposableCollection()) { // Validate item properties. model.ValidateOrganisationData(responseData); if (responseData.HasControlErrors()) return Json(responseData); // Retrieve organisation. SysId organisationId = model.OrganisationId.ToSysId(); SaxOrganisation organisation = AccountMgr.GetOrganisationById(organisationId); disposableItems.Add(organisation); if (organisation == null) { SaLogger.Warn(fn + " Failed to retrieve organisation for Id: '" + model.OrganisationId + "'"); return Json(responseData.SetMessage(messageTitle, Localiser["msg.error.item.id.not.found"])); } // Organisation address. SaxItemAddress address = ItemDataMgr.GetFirstItemAddressByItemAndType(organisation.GetItemId()); disposableItems.Add(address); // Check for uploaded logo image. ItemId organisationItemId = organisation.GetItemId(); SaxItemImage itemImageLogoUploaded = ItemDataMgr.GetItemImage(organisationItemId, Sax.ImageType.OrganisationLogo_Upload, SaxItemImage.StatusCat.ActiveOnly); disposableItems.Add(itemImageLogoUploaded); if (itemImageLogoUploaded != null) { // Retrieve current OrganisationLogo image. SaxItemImage itemImageLogo = ItemDataMgr.GetItemImage(organisationItemId, Sax.ImageType.OrganisationLogo, SaxItemImage.StatusCat.Any); if (itemImageLogo == null) itemImageLogo = ItemDataMgr.CreateItemImage(organisationItemId, Sax.ImageType.OrganisationLogo); disposableItems.Add(itemImageLogo); // Copy properties from uploaded image. itemImageLogo.Filename = itemImageLogoUploaded.Filename; itemImageLogo.Mime = itemImageLogoUploaded.Mime; itemImageLogo.ContentType = itemImageLogoUploaded.ContentType; itemImageLogo.Width = itemImageLogoUploaded.Width; itemImageLogo.Height = itemImageLogoUploaded.Height; itemImageLogo.ImageData = itemImageLogoUploaded.ImageData; itemImageLogo.Status = SaxItemImage.DefaultStatus; if (!SysId.IsValid(itemImageLogo.Id)) { if (!ItemDataMgr.InsertItemImage(itemImageLogo, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to insert logo image - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetControlError("AccountContactImage", Localiser["msg.error.item.insert.failed"])); } } else { if (!ItemDataMgr.UpdateItemImage(itemImageLogo, DbUpdateInfo)) { SaLogger.Warn(fn + " Failed to update logo image - " + ItemDataMgr.ErrorStateMessage); return Json(responseData.SetControlError("AccountContactImage", Localiser["msg.error.item.update.failed"])); } } // Logically delete the uplaoded image. itemImageLogoUploaded.Status = SaStatus.Deleted; if (!ItemDataMgr.UpdateItemImage(itemImageLogoUploaded, DbUpdateInfo)) SaLogger.Warn(fn + " Failed to logically delete uploaded logo image - " + ItemDataMgr.ErrorStateMessage); } // Construct response. PopulateOrganisationResponseImagesData(organisation, address, responseData.organisation); } // Complete response. responseData.Success = true; return Json(responseData); } //------------------------------------------------------------------- } //======================================================================= }