protected override void PrepareForUpdateChildrenMasterPages(bool isNew, BlogPost entity, BlogPostViewModel model, out IList<Guid> newMasterIds, out IList<Guid> oldMasterIds, out IList<Guid> childrenPageIds, out IList<MasterPage> existingChildrenMasterPages) { var modelExt = model as BlogPostViewModelExtender; if (!isNew && modelExt != null) { masterPageService.PrepareForUpdateChildrenMasterPages(entity, modelExt.MasterPageId, out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages); } else { newMasterIds = null; oldMasterIds = null; childrenPageIds = null; existingChildrenMasterPages = null; } }
protected virtual void PrepareForUpdateChildrenMasterPages(bool isNew, BlogPost entity, BlogPostViewModel model, out IList<Guid> newMasterIds, out IList<Guid> oldMasterIds, out IList<Guid> childrenPageIds, out IList<MasterPage> existingChildrenMasterPages) { newMasterIds = null; oldMasterIds = null; childrenPageIds = null; existingChildrenMasterPages = null; }
protected virtual BlogPostContent SaveContentWithStatusUpdate(bool isNew, BlogPostContent newContent, BlogPostViewModel request, IPrincipal principal) { return (BlogPostContent)contentService.SaveContentWithStatusUpdate(newContent, request.DesirableStatus); }
protected virtual IList<Tag> SaveTags(BlogPost blogPost, BlogPostViewModel request) { IList<Tag> newTags; tagService.SavePageTags(blogPost, request.Tags, out newTags); return newTags; }
/// <summary> /// Saves the blog post. /// </summary> /// <param name="request">The request.</param> /// <param name="childContentOptionValues">The child content option values.</param> /// <param name="principal">The principal.</param> /// <param name="errorMessages">The error messages.</param> /// <returns> /// Saved blog post entity /// </returns> /// <exception cref="System.ComponentModel.DataAnnotations.ValidationException"></exception> /// <exception cref="SecurityException">Forbidden: Access is denied.</exception> public BlogPost SaveBlogPost(BlogPostViewModel request, IList<ContentOptionValuesViewModel> childContentOptionValues, IPrincipal principal, out string[] errorMessages) { errorMessages = new string[0]; string[] roles; if (request.DesirableStatus == ContentStatus.Published) { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.PublishContent); roles = new[] { RootModuleConstants.UserRoles.PublishContent }; } else { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent); roles = new[] { RootModuleConstants.UserRoles.EditContent }; } var isNew = request.Id.HasDefaultValue(); var userCanEdit = securityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent); ValidateData(isNew, request); BlogPost blogPost; BlogPostContent content; PageContent pageContent; GetBlogPostAndContentEntities(request, principal, roles, ref isNew, out content, out pageContent, out blogPost); var beforeChange = new UpdatingBlogModel(blogPost); // Master page / layout Layout layout; Page masterPage; Region region; LoadDefaultLayoutAndRegion(out layout, out masterPage, out region); if (masterPage != null) { var level = accessControlService.GetAccessLevel(masterPage, principal); if (level < AccessLevel.Read) { var message = BlogGlobalization.SaveBlogPost_FailedToSave_InaccessibleMasterPage; const string logMessage = "Failed to save blog post. Selected master page for page layout is inaccessible."; throw new ValidationException(() => message, logMessage); } } if (pageContent.Region == null) { pageContent.Region = region; } // Load master pages for updating page's master path and page's children master path IList<Guid> newMasterIds; IList<Guid> oldMasterIds; IList<Guid> childrenPageIds; IList<MasterPage> existingChildrenMasterPages; PrepareForUpdateChildrenMasterPages(isNew, blogPost, request, out newMasterIds, out oldMasterIds, out childrenPageIds, out existingChildrenMasterPages); // TODO: TEST AND TRY TO FIX IT: TRANSACTION HERE IS REQUIRED! // UnitOfWork.BeginTransaction(); // NOTE: this causes concurrent data exception. Redirect redirectCreated = null; if (!isNew && userCanEdit && !string.Equals(blogPost.PageUrl, request.BlogUrl) && !string.IsNullOrWhiteSpace(request.BlogUrl)) { request.BlogUrl = urlService.FixUrl(request.BlogUrl); pageService.ValidatePageUrl(request.BlogUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(blogPost.PageUrl, request.BlogUrl); if (redirect != null) { repository.Save(redirect); redirectCreated = redirect; } } blogPost.PageUrl = urlService.FixUrl(request.BlogUrl); } // Push to change modified data each time. blogPost.ModifiedOn = DateTime.Now; if (userCanEdit) { blogPost.Title = request.Title; blogPost.Description = request.IntroText; blogPost.Author = request.AuthorId.HasValue ? repository.AsProxy<Author>(request.AuthorId.Value) : null; blogPost.Category = request.CategoryId.HasValue ? repository.AsProxy<Category>(request.CategoryId.Value) : null; blogPost.Image = (request.Image != null && request.Image.ImageId.HasValue) ? repository.AsProxy<MediaImage>(request.Image.ImageId.Value) : null; if (isNew || request.DesirableStatus == ContentStatus.Published) { blogPost.ActivationDate = request.LiveFromDate; blogPost.ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate); } } if (isNew) { if (!string.IsNullOrWhiteSpace(request.BlogUrl)) { blogPost.PageUrl = urlService.FixUrl(request.BlogUrl); pageService.ValidatePageUrl(blogPost.PageUrl); } else { blogPost.PageUrl = CreateBlogPermalink(request.Title, null, blogPost.Category != null ? (Guid?)blogPost.Category.Id : null); } blogPost.MetaTitle = request.MetaTitle ?? request.Title; if (masterPage != null) { blogPost.MasterPage = masterPage; masterPageService.SetPageMasterPages(blogPost, masterPage.Id); } else { blogPost.Layout = layout; } UpdateStatus(blogPost, request.DesirableStatus); AddDefaultAccessRules(blogPost, principal, masterPage); } else if (request.DesirableStatus == ContentStatus.Published || blogPost.Status == PageStatus.Preview) { // Update only if publishing or current status is preview. // Else do not change, because it may change from published to draft status UpdateStatus(blogPost, request.DesirableStatus); } // Create content. var newContent = new BlogPostContent { Id = content != null ? content.Id : Guid.Empty, Name = request.Title, Html = request.Content ?? string.Empty, EditInSourceMode = request.EditInSourceMode, ActivationDate = request.LiveFromDate, ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate) }; // Preserve content if user is not authorized to change it. if (!userCanEdit) { if (content == null) { throw new SecurityException("Forbidden: Access is denied."); // User has no rights to create new content. } var contentToPublish = (BlogPostContent)(content.History != null ? content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? content : content); newContent.Name = contentToPublish.Name; newContent.Html = contentToPublish.Html; } content = SaveContentWithStatusUpdate(isNew, newContent, request, principal); pageContent.Content = content; optionService.SaveChildContentOptions(content, childContentOptionValues, request.DesirableStatus); blogPost.PageUrlHash = blogPost.PageUrl.UrlHash(); blogPost.UseCanonicalUrl = request.UseCanonicalUrl; MapExtraProperties(isNew, blogPost, content, pageContent, request, principal); // Notify about page properties changing. var cancelEventArgs = Events.BlogEvents.Instance.OnBlogChanging(beforeChange, new UpdatingBlogModel(blogPost)); if (cancelEventArgs.Cancel) { errorMessages = cancelEventArgs.CancellationErrorMessages.ToArray(); return null; } repository.Save(blogPost); repository.Save(content); repository.Save(pageContent); masterPageService.UpdateChildrenMasterPages(existingChildrenMasterPages, oldMasterIds, newMasterIds, childrenPageIds); pageContent.Content = content; blogPost.PageContents = new [] {pageContent}; IList<Tag> newTags = null; if (userCanEdit) { newTags = SaveTags(blogPost, request); } // Commit unitOfWork.Commit(); // Notify about new created tags. Events.RootEvents.Instance.OnTagCreated(newTags); // Notify about new or updated blog post. if (isNew) { Events.BlogEvents.Instance.OnBlogCreated(blogPost); } else { Events.BlogEvents.Instance.OnBlogUpdated(blogPost); } // Notify about redirect creation. if (redirectCreated != null) { Events.PageEvents.Instance.OnRedirectCreated(redirectCreated); } return blogPost; }
protected override void ValidateData(bool isNew, BlogPostViewModel model) { base.ValidateData(isNew, model); var modelExt = model as BlogPostViewModelExtender; if (modelExt != null) { // Validate technical info: if at least one of techincal fields are not null and at least one is null, throw an exception if (!model.ContentId.HasDefaultValue() || modelExt.PageContentId.HasValue || modelExt.RegionId.HasValue) { if (model.ContentId.HasDefaultValue()) { const string message = "Blog post content ID should be specified if technical info is set."; throw new ValidationException(() => message, message); } if (!modelExt.PageContentId.HasValue || modelExt.PageContentId.Value.HasDefaultValue()) { const string message = "Page content ID should be specified if technical info is set."; throw new ValidationException(() => message, message); } if (!modelExt.RegionId.HasValue || modelExt.RegionId.Value.HasDefaultValue()) { const string message = "Region ID should be specified if technical info is set."; throw new ValidationException(() => message, message); } } // Validate if (!isNew) { if (!modelExt.LayoutId.HasValue && !modelExt.MasterPageId.HasValue) { const string message = "Master page id or layout id should be set when updating blog post."; throw new ValidationException(() => message, message); } if (string.IsNullOrWhiteSpace(model.BlogUrl)) { const string message = "Blog post URL cannot be null when updating blog post."; throw new ValidationException(() => message, message); } } } }
private void AssertBlogPostUrl(BlogPostViewModel blog) { Assert.IsFalse(blog.BlogUrl.Contains(".aspx")); Assert.IsFalse(blog.BlogUrl.Contains(".asp")); Assert.IsFalse(blog.BlogUrl.Contains(".html")); Assert.IsFalse(blog.BlogUrl.Contains(".htm")); Assert.IsFalse(blog.BlogUrl.Contains(".php")); }
protected virtual void ValidateData(bool isNew, BlogPostViewModel model) { // Do nothing }
private BlogPostViewModel MapViewModel(BlogMLPost blogML, bool useOriginalUrls, BlogPostImportResult modification = null, List<string> unsavedUrls = null) { var model = new BlogPostViewModel { Title = blogML.PostName ?? blogML.Title, IntroText = blogML.Excerpt != null ? blogML.Excerpt.UncodedText : null, LiveFromDate = blogML.DateCreated.Date, LiveToDate = null, DesirableStatus = ContentStatus.Published, Content = blogML.Content != null ? blogML.Content.UncodedText : null }; if (modification != null) { model.BlogUrl = modification.PageUrl; model.Title = modification.Title; } else if (useOriginalUrls) { model.BlogUrl = blogService.CreateBlogPermalink(FixUrl(blogML.PostUrl), unsavedUrls); } else { model.BlogUrl = blogService.CreateBlogPermalink(blogML.Title, unsavedUrls); } return model; }
protected override void GetBlogPostAndContentEntities(BlogPostViewModel model, IPrincipal principal, string[] roles, ref bool isNew, out BlogPostContent content, out PageContent pageContent , out BlogPost blogPost) { var modelExt = model as BlogPostViewModelExtender; if (!isNew && modelExt != null) { content = null; pageContent = null; blogPost = repository .AsQueryable<BlogPost>(bp => bp.Id == model.Id) .FetchMany(bp => bp.AccessRules) .FetchMany(bp => bp.PageTags) .ThenFetch(pt => pt.Tag) .ToList() .FirstOrDefault(); if (blogPost != null) { if (configuration.Security.AccessControlEnabled) { accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles); } if (modelExt.PageContentId.HasValue) { content = repository .AsQueryable<BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == model.Id && !x.IsDeleted && x.Id == modelExt.PageContentId.Value && !x.IsDeleted && c.Id == model.ContentId)) .ToFuture() .FirstOrDefault(); if (content == null) { const string message = "Cannot find a blog post content by specified blog post content and Id and page content Id."; var logMessage = string.Format("{0} BlogId: {1}, BlogPostContentId: {2}, PageContentId: {3}", message, model.Id, model.ContentId, modelExt.PageContentId); throw new ValidationException(() => message, logMessage); } pageContent = repository.First<PageContent>(pc => pc.Id == modelExt.PageContentId.Value); } else { content = repository .AsQueryable<BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == model.Id && !x.IsDeleted) && !c.IsDeleted) .ToFuture() .FirstOrDefault(); if (content != null) { var contentRef = content; pageContent = repository.FirstOrDefault<PageContent>(c => c.Page.Id == model.Id && !c.IsDeleted && c.Content == contentRef); } } } isNew = blogPost == null; if (isNew) { blogPost = new BlogPost(); pageContent = new PageContent { Page = blogPost }; } } else { base.GetBlogPostAndContentEntities(model, principal, roles, ref isNew, out content, out pageContent, out blogPost); } }
protected override IList<Tag> SaveTags(BlogPost blogPost, BlogPostViewModel request) { if (request.Tags != null) { return base.SaveTags(blogPost, request); } return null; }
protected override void MapExtraProperties(bool isNew, BlogPost entity, BlogPostContent content, PageContent pageContent, BlogPostViewModel model, IPrincipal principal) { var currentVersion = entity.Version; base.MapExtraProperties(isNew, entity, content, pageContent, model, principal); var modelExt = model as BlogPostViewModelExtender; if (modelExt != null) { // Restore version if not set from the extended model if (model.Version <= 0) { entity.Version = currentVersion; } entity.SecondaryImage = modelExt.SecondaryImageId.HasValue ? repository.AsProxy<MediaImage>(modelExt.SecondaryImageId.Value) : null; entity.FeaturedImage = modelExt.FeaturedImageId.HasValue ? repository.AsProxy<MediaImage>(modelExt.FeaturedImageId.Value) : null; entity.IsArchived = modelExt.IsArchived; entity.UseNoFollow = modelExt.UseNoFollow; entity.UseNoIndex = modelExt.UseNoIndex; entity.MetaKeywords = modelExt.MetaKeywords; entity.MetaDescription = modelExt.MetaDescription; // If creating new and content / page content / region ids are set, enforce them to be set explicitly if (isNew && !model.ContentId.HasDefaultValue() && modelExt.PageContentId.HasValue && modelExt.RegionId.HasValue) { pageContent.Id = modelExt.PageContentId.Value; pageContent.Region = repository.AsProxy<Region>(modelExt.RegionId.Value); } // Set blog post Id, if it's set if (isNew && !model.Id.HasDefaultValue()) { entity.Id = model.Id; } // PublishedOn if (isNew && entity.Status == PageStatus.Published && modelExt.PublishedOn.HasValue) { entity.PublishedOn = modelExt.PublishedOn.Value; } // Set layout / master page if (modelExt.MasterPageId.HasValue) { entity.Layout = null; if (isNew) { entity.MasterPage = repository .AsQueryable<Page>(p => p.Id == modelExt.MasterPageId.Value) .FetchMany(p => p.AccessRules) .ToList() .FirstOne(); if (modelExt.AccessRules == null) { AddDefaultAccessRules(entity, principal, entity.MasterPage); } masterPageService.SetPageMasterPages(entity, entity.MasterPage.Id); } else { entity.MasterPage = repository.AsProxy<Page>(modelExt.MasterPageId.Value); } } else if (modelExt.LayoutId.HasValue) { entity.Layout = repository.AsProxy<Layout>(modelExt.LayoutId.Value); entity.MasterPage = null; if (isNew && modelExt.AccessRules == null) { AddDefaultAccessRules(entity, principal, null); } } // Add access rules from the request if (modelExt.AccessRules != null) { if (entity.AccessRules == null) { entity.AccessRules = new List<AccessRule>(); } else { entity.AccessRules.RemoveDuplicateEntities(); } var accessRules = modelExt.AccessRules .Select(r => (IAccessRule)new AccessRule { AccessLevel = (AccessLevel)(int)r.AccessLevel, Identity = r.Identity, IsForRole = r.IsForRole }).ToList(); accessControlService.UpdateAccessControl(entity, accessRules); } } }
protected override BlogPostContent SaveContentWithStatusUpdate(bool isNew, BlogPostContent newContent, BlogPostViewModel model, IPrincipal principal) { var modelExt = model as BlogPostViewModelExtender; if (isNew && modelExt != null && !modelExt.ContentId.HasDefaultValue()) { if (model.DesirableStatus == ContentStatus.Published) { newContent.PublishedOn = modelExt.PublishedOn ?? DateTime.Now; newContent.PublishedByUser = principal.Identity.Name; // TODO: pass published by user newContent.PublishedByUser = !string.IsNullOrEmpty(request.Data.PublishedByUser) ? request.Data.PublishedByUser : securityService.CurrentPrincipalName; } newContent.Status = model.DesirableStatus; newContent.Id = modelExt.ContentId; repository.Save(newContent); return newContent; } return base.SaveContentWithStatusUpdate(isNew, newContent, model, principal); }
protected virtual void GetBlogPostAndContentEntities(BlogPostViewModel request, IPrincipal principal, string[] roles, ref bool isNew, out BlogPostContent content, out PageContent pageContent , out BlogPost blogPost) { content = null; pageContent = null; // Loading blog post and it's content, or creating new, if such not exists if (!isNew) { var blogPostFuture = repository .AsQueryable<BlogPost>(b => b.Id == request.Id) .ToFuture(); content = repository .AsQueryable<BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == request.Id && !x.IsDeleted)) .ToFuture() .FirstOrDefault(); blogPost = blogPostFuture.FirstOne(); if (configuration.Security.AccessControlEnabled) { accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles); } if (content != null) { // Check if user has confirmed the deletion of content if (!request.IsUserConfirmed && blogPost.IsMasterPage) { var hasAnyChildren = contentService.CheckIfContentHasDeletingChildren(blogPost.Id, content.Id, request.Content); if (hasAnyChildren) { var message = PagesGlobalization.SaveContent_ContentHasChildrenContents_RegionDeleteConfirmationMessage; var logMessage = string.Format("User is trying to delete content regions which has children contents. Confirmation is required. ContentId: {0}, PageId: {1}", content.Id, blogPost.Id); throw new ConfirmationRequestException(() => message, logMessage); } } var bpRef = blogPost; var contentRef = content; pageContent = repository.FirstOrDefault<PageContent>(c => c.Page == bpRef && !c.IsDeleted && c.Content == contentRef); } } else { blogPost = new BlogPost(); } if (pageContent == null) { pageContent = new PageContent { Page = blogPost }; } }
private bool ValidateModel(BlogPostViewModel blogPostModel, BlogMLPost blogML, out BlogPostImportResult failedResult) { failedResult = null; if (string.IsNullOrWhiteSpace(blogML.ID)) { failedResult = new BlogPostImportResult { Title = blogML.Title, PageUrl = blogML.PostUrl, Success = false, ErrorMessage = BlogGlobalization.ImportBlogPosts_ImportingBlogPostIdIsNotSet_Message, Id = blogML.ID }; return false; } var validationContext = new ValidationContext(blogPostModel, null, null); var validationResults = new List<ValidationResult>(); if (!Validator.TryValidateObject(blogPostModel, validationContext, validationResults, true) && validationResults.Count > 0) { failedResult = new BlogPostImportResult { Title = blogML.Title, PageUrl = blogML.PostUrl, Success = false, ErrorMessage = validationResults[0].ErrorMessage, Id = blogML.ID }; return false; } try { pageService.ValidatePageUrl(blogPostModel.BlogUrl); } catch (Exception exc) { failedResult = new BlogPostImportResult { Title = blogML.Title, PageUrl = blogML.PostUrl, Success = false, ErrorMessage = exc.Message, Id = blogML.ID }; return false; } return true; }
protected virtual void MapExtraProperties(bool isNew, BlogPost entity, BlogPostContent content, PageContent pageContent, BlogPostViewModel model, IPrincipal principal) { entity.Version = model.Version; }
public ActionResult SaveBlogPost(BlogPostViewModel model) { var response = GetCommand<SaveBlogPostCommand>().ExecuteCommand(model); if (response != null) { if (model.DesirableStatus != ContentStatus.Preview && model.Id.HasDefaultValue()) { Messages.AddSuccess(BlogGlobalization.CreatePost_CreatedSuccessfully_Message); } } return WireJson(response != null, response); }
private void AssertBlogPost(BlogPostViewModel blog) { Assert.AreEqual(blog.LiveFromDate, new DateTime(2006, 09, 05)); Assert.AreEqual(blog.Title, "CS Dev Guide: Send Emails"); Assert.AreEqual(blog.IntroText, "CS Dev Guide: Send Emails - Intro Text"); Assert.AreEqual(blog.DesirableStatus, ContentStatus.Published); Assert.AreEqual(blog.Content, "<p>Any web application needs a way to send emails to different kinds of its users. This capability is provided in Community Server from early versions. Sending emails is one of easiest parts of Community Server development.</p><p>To send emails in Community Serve you have two options: using pre-defined email templates for some common situations or create an email manually.</p><p>First option is easy to implement. Community Server has provided several default templates for your emails and you can add your own templates via resource files as well. <em>CommunityServer.Components.Emails</em> namespace has many methods that get some parameters then create and send an email based on the template they have.</p><p>For example you can send a notification email to user to let him know his account is created.</p><div style=\"background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new\"><p style=\"margin: 0px\"><span style=\"color: blue\">private</span> <span style=\"color: blue\">void</span> SendEmail(<span style=\"color: blue\">string</span> username, <span style=\"color: blue\">string</span> password</p><p style=\"margin: 0px\"> , <span style=\"color: blue\">string</span> email)</p><p style=\"margin: 0px\">{</p><p style=\"margin: 0px\"> <span style=\"color: teal\">User</span> user = <span style=\"color: blue\">new</span> <span style=\"color: teal\">User</span>();</p><p style=\"margin: 0px\"> user.Username = username;</p><p style=\"margin: 0px\"> user.Password = password;</p><p style=\"margin: 0px\"> user.Email = email;</p><p style=\"margin: 0px\"> </p><p style=\"margin: 0px\"> <span style=\"color: teal\">Emails</span>.UserCreate(user, password);</p><p style=\"margin: 0px\">}</p></div><p>These methods add emails to queue automatically. You can use <em>Emails.SendQueuedEmails()</em> method to send all queued emails to recipients. This method takes three parameters: an integer value for failure interval, an integer value that specifies the maximum number of tries of sending process failed and a <em>SiteSettings</em> object.</p><div style=\"background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new\"><p style=\"margin: 0px\"><span style=\"color: blue\">private</span> <span style=\"color: blue\">void</span> SendQueuedEmails()</p><p style=\"margin: 0px\">{</p><p style=\"margin: 0px\"> <span style=\"color: teal\">Emails</span>.SendQueuedEmails(5, 5,</p><p style=\"margin: 0px\"> <span style=\"color: teal\">CSContext</span>.Current.SiteSettings);</p><p style=\"margin: 0px\">}</p></div><p>Second option to send emails is manual option. This is useful when you want to send an email but it doesn't fit to Community Server pre-defined templates.</p><p>This option is very similar to sending emails in ASP.NET 1.x. You need to create an instance of System.Web.Mail.MailMessage object, set its appropriate properties and add it to emails queue using Community Server APIs. You know MailMessage object is obsolete in ASP.NET 2.0 but Community Server accepts old objects to be able to work under ASP.NET 1.1. If you need more information about sending emails in ASP.NET 2.0, read my post about my SMTP component, Gopi, from <a href=\"http://nayyeri.net/archive/2006/05/20/Gopi-_2D00_-SMTP-component-for-.NET-2.0.asp\">here</a>.</p><p>Here is a sample of how to create a new MailMessage and add it to emails queue.</p><div style=\"background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new\"><p style=\"margin: 0px\"><span style=\"color: blue\">private</span> <span style=\"color: blue\">void</span> SendEmailManually()</p><p style=\"margin: 0px\">{</p><p style=\"margin: 0px\"> <span style=\"color: teal\">MailMessage</span> mail = <span style=\"color: blue\">new</span> <span style=\"color: teal\">MailMessage</span>();</p><p style=\"margin: 0px\"> mail.From = <span style=\"color: maroon\">"[email protected]"</span>;</p><p style=\"margin: 0px\"> mail.To = <span style=\"color: maroon\">"[email protected]"</span>;</p><p style=\"margin: 0px\"> </p><p style=\"margin: 0px\"> mail.Priority = <span style=\"color: teal\">MailPriority</span>.Normal;</p><p style=\"margin: 0px\"> mail.BodyFormat = <span style=\"color: teal\">MailFormat</span>.Text;</p><p style=\"margin: 0px\"> </p><p style=\"margin: 0px\"> mail.Body = <span style=\"color: maroon\">"Long Live Community Server!"</span>;</p><p style=\"margin: 0px\"> mail.Subject = <span style=\"color: maroon\">"Test Email"</span>;</p><p style=\"margin: 0px\"> </p><p style=\"margin: 0px\"> <span style=\"color: teal\">EmailQueueProvider</span>.Instance().QueueEmail(mail);</p><p style=\"margin: 0px\">}</p></div><p>You saw I used <em>EmailQueueProvider.Instance().QueueEmail()</em> method to add my email to queue. You can use <em>EmailQueueProvider.Instance()</em> object to deal with emails queue in Community Server. For instance you can remove an email from emails queue by passing its Guid to <em>EmailQueueProvider.Instance().DeleteQueuedEmail()</em> method.</p><div style=\"background: white none repeat scroll 0% 50%; font-size: 10pt; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; color: black; font-family: courier new\"><p style=\"margin: 0px\"><span style=\"color: blue\">private</span> <span style=\"color: blue\">void</span> DealWithEmails()</p><p style=\"margin: 0px\">{</p><p style=\"margin: 0px\"> <span style=\"color: teal\">EmailQueueProvider</span>.Instance()</p><p style=\"margin: 0px\"> .DeleteQueuedEmail(<span style=\"color: teal\">Guid</span>.NewGuid()); </p><p style=\"margin: 0px\">}</p></div><p><strong>Now playing: </strong>Modern Talking - You are not alone</p>"); Assert.AreEqual(blog.AuthorId, new Guid("7D601C36-7130-4031-95BC-578C34328143")); // Assert.AreEqual(blog.CategoryId, new Guid("B81ACA8C-93CD-48C0-8B7F-F9ADE3D1BAC8")); }
protected virtual void GetBlogPostAndContentEntities(BlogPostViewModel request, IPrincipal principal, string[] roles, ref bool isNew, out BlogPostContent content, out PageContent pageContent , out BlogPost blogPost) { content = null; pageContent = null; // Loading blog post and it's content, or creating new, if such not exists if (!isNew) { var blogPostFuture = repository .AsQueryable<BlogPost>(b => b.Id == request.Id) .ToFuture(); content = repository .AsQueryable<BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == request.Id && !x.IsDeleted)) .ToFuture() .FirstOrDefault(); blogPost = blogPostFuture.FirstOne(); if (configuration.Security.AccessControlEnabled) { accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles); } if (content != null) { // Check if user has confirmed the deletion of content if (!request.IsUserConfirmed && blogPost.IsMasterPage) { contentService.CheckIfContentHasDeletingChildrenWithException(blogPost.Id, content.Id, request.Content); } var bpRef = blogPost; var contentRef = content; pageContent = repository.FirstOrDefault<PageContent>(c => c.Page == bpRef && !c.IsDeleted && c.Content == contentRef); } } else { blogPost = new BlogPost(); } if (pageContent == null) { pageContent = new PageContent { Page = blogPost }; } }
/// <summary> /// Saves the blog post. /// </summary> /// <param name="request">The request.</param> /// <param name="principal">The principal.</param> /// <returns> /// Saved blog post entity /// </returns> public BlogPost SaveBlogPost(BlogPostViewModel request, IPrincipal principal) { string[] roles; if (request.DesirableStatus == ContentStatus.Published) { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.PublishContent); roles = new[] { RootModuleConstants.UserRoles.PublishContent }; } else { accessControlService.DemandAccess(principal, RootModuleConstants.UserRoles.EditContent); roles = new[] { RootModuleConstants.UserRoles.EditContent }; } Layout layout; Page masterPage; LoadLayout(out layout, out masterPage); if (masterPage != null) { var level = accessControlService.GetAccessLevel(masterPage, principal); if (level < AccessLevel.Read) { var message = BlogGlobalization.SaveBlogPost_FailedToSave_InaccessibleMasterPage; const string logMessage = "Failed to save blog post. Selected master page for page layout is inaccessible."; throw new ValidationException(() => message, logMessage); } } var region = LoadRegion(layout, masterPage); var isNew = request.Id.HasDefaultValue(); var userCanEdit = securityService.IsAuthorized(RootModuleConstants.UserRoles.EditContent); // UnitOfWork.BeginTransaction(); // NOTE: this causes concurrent data exception. BlogPost blogPost; BlogPostContent content = null; PageContent pageContent = null; Pages.Models.Redirect redirectCreated = null; // Loading blog post and it's content, or creating new, if such not exists if (!isNew) { var blogPostFuture = repository .AsQueryable<BlogPost>(b => b.Id == request.Id) .ToFuture(); content = repository .AsQueryable<BlogPostContent>(c => c.PageContents.Any(x => x.Page.Id == request.Id && !x.IsDeleted)) .ToFuture() .FirstOrDefault(); blogPost = blogPostFuture.FirstOne(); if (cmsConfiguration.Security.AccessControlEnabled) { accessControlService.DemandAccess(blogPost, principal, AccessLevel.ReadWrite, roles); } if (content != null) { // Check if user has confirmed the deletion of content if (!request.IsUserConfirmed && blogPost.IsMasterPage) { var hasAnyChildren = contentService.CheckIfContentHasDeletingChildren(blogPost.Id, content.Id, request.Content); if (hasAnyChildren) { var message = PagesGlobalization.SaveContent_ContentHasChildrenContents_RegionDeleteConfirmationMessage; var logMessage = string.Format("User is trying to delete content regions which has children contents. Confirmation is required. ContentId: {0}, PageId: {1}", content.Id, blogPost.Id); throw new ConfirmationRequestException(() => message, logMessage); } } pageContent = repository.FirstOrDefault<PageContent>(c => c.Page == blogPost && !c.IsDeleted && c.Content == content); } if (userCanEdit && !string.Equals(blogPost.PageUrl, request.BlogUrl) && request.BlogUrl != null) { request.BlogUrl = urlService.FixUrl(request.BlogUrl); pageService.ValidatePageUrl(request.BlogUrl, request.Id); if (request.RedirectFromOldUrl) { var redirect = redirectService.CreateRedirectEntity(blogPost.PageUrl, request.BlogUrl); if (redirect != null) { repository.Save(redirect); redirectCreated = redirect; } } blogPost.PageUrl = urlService.FixUrl(request.BlogUrl); } } else { blogPost = new BlogPost(); } if (pageContent == null) { pageContent = new PageContent { Region = region, Page = blogPost }; } // Push to change modified data each time. blogPost.ModifiedOn = DateTime.Now; blogPost.Version = request.Version; if (userCanEdit) { blogPost.Title = request.Title; blogPost.Description = request.IntroText; blogPost.Author = request.AuthorId.HasValue ? repository.AsProxy<Author>(request.AuthorId.Value) : null; blogPost.Category = request.CategoryId.HasValue ? repository.AsProxy<Category>(request.CategoryId.Value) : null; blogPost.Image = (request.Image != null && request.Image.ImageId.HasValue) ? repository.AsProxy<MediaImage>(request.Image.ImageId.Value) : null; if (isNew || request.DesirableStatus == ContentStatus.Published) { blogPost.ActivationDate = request.LiveFromDate; blogPost.ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate); } } if (isNew) { if (!string.IsNullOrWhiteSpace(request.BlogUrl)) { blogPost.PageUrl = urlService.FixUrl(request.BlogUrl); pageService.ValidatePageUrl(blogPost.PageUrl); } else { blogPost.PageUrl = CreateBlogPermalink(request.Title); } blogPost.MetaTitle = request.MetaTitle ?? request.Title; if (masterPage != null) { blogPost.MasterPage = masterPage; masterPageService.SetPageMasterPages(blogPost, masterPage.Id); } else { blogPost.Layout = layout; } UpdateStatus(blogPost, request.DesirableStatus); AddDefaultAccessRules(blogPost, principal, masterPage); } else if (request.DesirableStatus == ContentStatus.Published || blogPost.Status == PageStatus.Preview) { // Update only if publishing or current status is preview. // Else do not change, because it may change from published to draft status UpdateStatus(blogPost, request.DesirableStatus); } // Create content. var newContent = new BlogPostContent { Id = content != null ? content.Id : Guid.Empty, Name = request.Title, Html = request.Content ?? string.Empty, EditInSourceMode = request.EditInSourceMode, ActivationDate = request.LiveFromDate, ExpirationDate = TimeHelper.FormatEndDate(request.LiveToDate) }; // Preserve content if user is not authorized to change it. if (!userCanEdit) { if (content == null) { throw new SecurityException("Forbidden: Access is denied."); // User has no rights to create new content. } var contentToPublish = (BlogPostContent)(content.History != null ? content.History.FirstOrDefault(c => c.Status == ContentStatus.Draft) ?? content : content); newContent.Name = contentToPublish.Name; newContent.Html = contentToPublish.Html; } content = (BlogPostContent)contentService.SaveContentWithStatusUpdate(newContent, request.DesirableStatus); pageContent.Content = content; blogPost.PageUrlHash = blogPost.PageUrl.UrlHash(); blogPost.UseCanonicalUrl = request.UseCanonicalUrl; repository.Save(blogPost); repository.Save(content); repository.Save(pageContent); pageContent.Content = content; blogPost.PageContents = new [] {pageContent}; IList<Tag> newTags = null; if (userCanEdit) { tagService.SavePageTags(blogPost, request.Tags, out newTags); } // Commit unitOfWork.Commit(); // Notify about new or updated blog post. if (isNew) { Events.BlogEvents.Instance.OnBlogCreated(blogPost); } else { Events.BlogEvents.Instance.OnBlogUpdated(blogPost); } // Notify about new created tags. Events.RootEvents.Instance.OnTagCreated(newTags); // Notify about redirect creation. if (redirectCreated != null) { Events.PageEvents.Instance.OnRedirectCreated(redirectCreated); } return blogPost; }
public ActionResult SaveBlogPost(BlogPostViewModel model) { try { var response = GetCommand<SaveBlogPostCommand>().ExecuteCommand(model); if (response != null) { if (model.DesirableStatus != ContentStatus.Preview && model.Id.HasDefaultValue()) { Messages.AddSuccess(BlogGlobalization.CreatePost_CreatedSuccessfully_Message); } } return WireJson(response != null, response); } catch (ConfirmationRequestException exc) { return WireJson(false, new { ConfirmationMessage = exc.Resource() }); } }