using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Publishing; using Umbraco.Core.Services; using Umbraco.Web.Mvc; using umbraco; using umbraco.cms.businesslogic.web; namespace Umbraco.Web.WebServices { /// /// A REST controller used for the publish dialog in order to publish bulk items at once /// public class BulkPublishController : UmbracoAuthorizedController { /// /// Publishes an document /// /// /// true to publish descendants as well /// true to publish documents that are unpublished /// A Json array containing objects with the child id's of the document and it's current published status [HttpPost] public JsonResult PublishDocument(int documentId, bool publishDescendants, bool includeUnpublished) { var content = Services.ContentService.GetById(documentId); var doc = new Document(content); //var contentService = (ContentService) Services.ContentService; if (publishDescendants == false) { //var result = contentService.SaveAndPublishInternal(content); var result = doc.SaveAndPublish(UmbracoUser.Id); return Json(new { success = result.Success, message = GetMessageForStatus(result.Result) }); } else { /*var result = ((ContentService) Services.ContentService) .PublishWithChildrenInternal(content, UmbracoUser.Id, includeUnpublished) .ToArray();*/ var result = doc.PublishWithSubs(UmbracoUser.Id, includeUnpublished); return Json(new { success = result.All(x => x.Success), message = GetMessageForStatuses(result.Select(x => x.Result), content) }); } } private string GetMessageForStatuses(IEnumerable statuses, IContent doc) { //if all are successful then just say it was successful if (statuses.All(x => ((int) x.StatusType) < 10)) { return ui.Text("publish", "nodePublishAll", doc.Name, UmbracoUser); } //if they are not all successful the we'll add each error message to the output (one per line) var sb = new StringBuilder(); foreach (var msg in statuses .Where(x => ((int)x.StatusType) >= 10) .Select(GetMessageForStatus) .Where(msg => msg.IsNullOrWhiteSpace() == false)) { sb.AppendLine(msg.Trim()); } return sb.ToString(); } private string GetMessageForStatus(PublishStatus status) { switch (status.StatusType) { case PublishStatusType.Success: case PublishStatusType.SuccessAlreadyPublished: return ui.Text("publish", "nodePublish", status.ContentItem.Name, UmbracoUser); case PublishStatusType.FailedPathNotPublished: return ui.Text("publish", "contentPublishedFailedByParent", string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser); case PublishStatusType.FailedHasExpired: case PublishStatusType.FailedAwaitingRelease: case PublishStatusType.FailedIsTrashed: return ""; //we will not notify about this type of failure... or should we ? case PublishStatusType.FailedCancelledByEvent: return ui.Text("publish", "contentPublishedFailedByEvent", string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), UmbracoUser); case PublishStatusType.FailedContentInvalid: return ui.Text("publish", "contentPublishedFailedInvalid", new []{ string.Format("{0} ({1})", status.ContentItem.Name, status.ContentItem.Id), string.Join(",", status.InvalidProperties.Select(x => x.Alias)) }, UmbracoUser); default: return status.StatusType.ToString(); } } } }