private PublishStatusType CheckAndLogIsValid(IContent content) { //Content contains invalid property values and can therefore not be published - fire event? if (content.IsValid() == false) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because of invalid properties.", content.Name, content.Id)); return PublishStatusType.FailedContentInvalid; } return PublishStatusType.Success; }
/// <summary> /// Publishes a <see cref="IContent"/> object and all its children /// </summary> /// <param name="content">The <see cref="IContent"/> to publish along with its children</param> /// <param name="userId">Optional Id of the User issueing the publishing</param> /// <param name="includeUnpublished">If set to true, this will also publish descendants that are completely unpublished, normally this will only publish children that have previously been published</param> /// <returns> /// A list of publish statues. If the parent document is not valid or cannot be published because it's parent(s) is not published /// then the list will only contain one status item, otherwise it will contain status items for it and all of it's descendants that /// are to be published. /// </returns> private IEnumerable<Attempt<PublishStatus>> PublishWithChildrenDo( IContent content, int userId = 0, bool includeUnpublished = false) { if (content == null) throw new ArgumentNullException("content"); using (new WriteLock(Locker)) { var result = new List<Attempt<PublishStatus>>(); //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because its parent or one of its ancestors is not published.", content.Name, content.Id)); result.Add(new Attempt<PublishStatus>(false, new PublishStatus(content, PublishStatusType.FailedPathNotPublished))); return result; } //Content contains invalid property values and can therefore not be published - fire event? if (!content.IsValid()) { LogHelper.Info<ContentService>( string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.", content.Name, content.Id)); result.Add( new Attempt<PublishStatus>(false, new PublishStatus(content, PublishStatusType.FailedContentInvalid) { InvalidProperties = ((ContentBase) content).LastInvalidProperties })); return result; } //Consider creating a Path query instead of recursive method: //var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path)); var updated = new List<IContent>(); var list = new List<IContent>(); list.Add(content); //include parent item list.AddRange(GetDescendants(content)); var internalStrategy = (PublishingStrategy)_publishingStrategy; //Publish and then update the database with new status var publishedOutcome = internalStrategy.PublishWithChildrenInternal(list, userId, includeUnpublished).ToArray(); var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateContentRepository(uow)) { //NOTE The Publish with subpages-dialog was used more as a republish-type-thing, so we'll have to include PublishStatusType.SuccessAlreadyPublished //in the updated-list, so the Published event is triggered with the expected set of pages and the xml is updated. foreach (var item in publishedOutcome.Where( x => x.Success || x.Result.StatusType == PublishStatusType.SuccessAlreadyPublished)) { item.Result.ContentItem.WriterId = userId; repository.AddOrUpdate(item.Result.ContentItem); updated.Add(item.Result.ContentItem); } uow.Commit(); foreach (var c in updated) { var xml = c.ToXml(); var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) }; var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = c.Id }) != null; var r = exists ? uow.Database.Update(poco) : Convert.ToInt32(uow.Database.Insert(poco)); } } //Save xml to db and call following method to fire event: _publishingStrategy.PublishingFinalized(updated, false); Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId, content.Id); return publishedOutcome; } }
/// <summary> /// Publishes a <see cref="IContent"/> object and all its children /// </summary> /// <param name="content">The <see cref="IContent"/> to publish along with its children</param> /// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param> /// <param name="userId">Optional Id of the User issueing the publishing</param> /// <returns>True if publishing succeeded, otherwise False</returns> private bool PublishWithChildrenDo(IContent content, bool omitCacheRefresh = false, int userId = 0) { //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because its parent or one of its ancestors is not published.", content.Name, content.Id)); return false; } //Content contains invalid property values and can therefore not be published - fire event? if (!content.IsValid()) { LogHelper.Info<ContentService>( string.Format("Content '{0}' with Id '{1}' could not be published because of invalid properties.", content.Name, content.Id)); return false; } //Consider creating a Path query instead of recursive method: //var query = Query<IContent>.Builder.Where(x => x.Path.StartsWith(content.Path)); var updated = new List<IContent>(); var list = new List<IContent>(); list.Add(content); list.AddRange(GetDescendants(content)); //Publish and then update the database with new status var published = _publishingStrategy.PublishWithChildren(list, userId); if (published) { var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateContentRepository(uow)) { //Only loop through content where the Published property has been updated foreach (var item in list.Where(x => ((ICanBeDirty)x).IsPropertyDirty("Published"))) { item.WriterId = userId; repository.AddOrUpdate(item); updated.Add(item); } uow.Commit(); foreach (var c in updated) { var xml = c.ToXml(); var poco = new ContentXmlDto { NodeId = c.Id, Xml = xml.ToString(SaveOptions.None) }; var exists = uow.Database.FirstOrDefault<ContentXmlDto>("WHERE nodeId = @Id", new { Id = c.Id }) != null; int result = exists ? uow.Database.Update(poco) : Convert.ToInt32(uow.Database.Insert(poco)); } } //Save xml to db and call following method to fire event: if (omitCacheRefresh == false) _publishingStrategy.PublishingFinalized(updated, false); Audit.Add(AuditTypes.Publish, "Publish with Children performed by user", userId, content.Id); } return published; }
/// <summary> /// Saves and Publishes a single <see cref="IContent"/> object /// </summary> /// <param name="content">The <see cref="IContent"/> to save and publish</param> /// <param name="omitCacheRefresh">Optional boolean to avoid having the cache refreshed when calling this Publish method. By default this method will update the cache.</param> /// <param name="userId">Optional Id of the User issueing the publishing</param> /// <param name="raiseEvents">Optional boolean indicating whether or not to raise save events.</param> /// <returns>True if publishing succeeded, otherwise False</returns> private bool SaveAndPublishDo(IContent content, bool omitCacheRefresh = false, int userId = 0, bool raiseEvents = true) { if (raiseEvents) { if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(content), this)) return false; } using (new WriteLock(Locker)) { //Has this content item previously been published? If so, we don't need to refresh the children var previouslyPublished = HasPublishedVersion(content.Id); var validForPublishing = true; //Check if parent is published (although not if its a root node) - if parent isn't published this Content cannot be published if (content.ParentId != -1 && content.ParentId != -20 && IsPublishable(content) == false) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because its parent is not published.", content.Name, content.Id)); validForPublishing = false; } //Content contains invalid property values and can therefore not be published - fire event? if (!content.IsValid()) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because of invalid properties.", content.Name, content.Id)); validForPublishing = false; } //Publish and then update the database with new status bool published = validForPublishing && _publishingStrategy.Publish(content, userId); var uow = _uowProvider.GetUnitOfWork(); using (var repository = _repositoryFactory.CreateContentRepository(uow)) { //Since this is the Save and Publish method, the content should be saved even though the publish fails or isn't allowed content.WriterId = userId; repository.AddOrUpdate(content); uow.Commit(); var xml = content.ToXml(); //Preview Xml var previewPoco = new PreviewXmlDto { NodeId = content.Id, Timestamp = DateTime.Now, VersionId = content.Version, Xml = xml.ToString(SaveOptions.None) }; var previewExists = uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsPreviewXml WHERE nodeId = @Id AND versionId = @Version", new { Id = content.Id, Version = content.Version }) != 0; int previewResult = previewExists ? uow.Database.Update<PreviewXmlDto>( "SET xml = @Xml, timestamp = @Timestamp WHERE nodeId = @Id AND versionId = @Version", new { Xml = previewPoco.Xml, Timestamp = previewPoco.Timestamp, Id = previewPoco.NodeId, Version = previewPoco.VersionId }) : Convert.ToInt32(uow.Database.Insert(previewPoco)); if (published) { //Content Xml var contentPoco = new ContentXmlDto { NodeId = content.Id, Xml = xml.ToString(SaveOptions.None) }; var contentExists = uow.Database.ExecuteScalar<int>("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId = @Id", new { Id = content.Id }) != 0; int contentResult = contentExists ? uow.Database.Update(contentPoco) : Convert.ToInt32(uow.Database.Insert(contentPoco)); } } if (raiseEvents) Saved.RaiseEvent(new SaveEventArgs<IContent>(content, false), this); //Save xml to db and call following method to fire event through PublishingStrategy to update cache if (published && omitCacheRefresh == false) _publishingStrategy.PublishingFinalized(content); //We need to check if children and their publish state to ensure that we 'republish' content that was previously published if (published && omitCacheRefresh == false && previouslyPublished == false && HasChildren(content.Id)) { var descendants = GetPublishedDescendants(content); _publishingStrategy.PublishingFinalized(descendants, false); } Audit.Add(AuditTypes.Publish, "Save and Publish performed by user", userId, content.Id); return published; } }
private bool CheckAndLogIsValid(IContent content) { //Content contains invalid property values and can therefore not be published - fire event? if (content.IsValid() == false) { LogHelper.Info<ContentService>( string.Format( "Content '{0}' with Id '{1}' could not be published because of invalid properties.", content.Name, content.Id)); return false; } return true; }