Fixes: U4-4770 Preview XML is not generated for many operations in the ContentService, also moves some more CRUD logic in the content service to the content repo.

This commit is contained in:
Shannon
2014-04-29 11:11:48 +10:00
parent aba1862811
commit b98fbbc75d
6 changed files with 75 additions and 27 deletions

View File

@@ -22,6 +22,12 @@ namespace Umbraco.Core.Models
Content = content;
}
public ContentXmlEntity(TContent content)
{
if (content == null) throw new ArgumentNullException("content");
Content = content;
}
public XElement Xml
{
get { return _xml(Content); }

View File

@@ -575,6 +575,15 @@ namespace Umbraco.Core.Persistence.Repositories
_contentXmlRepository.AddOrUpdate(new ContentXmlEntity<IContent>(contentExists, content, xml));
}
/// <summary>
/// Used to remove the content xml for a content item
/// </summary>
/// <param name="content"></param>
public void DeleteContentXml(IContent content)
{
_contentXmlRepository.Delete(new ContentXmlEntity<IContent>(content));
}
/// <summary>
/// Adds/updates preview xml
/// </summary>

View File

@@ -55,12 +55,14 @@ namespace Umbraco.Core.Persistence.Repositories
{
get { throw new NotImplementedException(); }
}
#endregion
protected override void PersistDeletedItem(ContentXmlEntity<TContent> entity)
{
throw new NotImplementedException();
//Remove 'published' xml from the cmsContentXml table for the unpublished content
Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = entity.Id });
}
#endregion
protected override void PersistNewItem(ContentXmlEntity<TContent> entity)
{

View File

@@ -46,6 +46,12 @@ namespace Umbraco.Core.Persistence.Repositories
/// <param name="xml"></param>
void AddOrUpdateContentXml(IContent content, Func<IContent, XElement> xml);
/// <summary>
/// Used to remove the content xml for a content item
/// </summary>
/// <param name="content"></param>
void DeleteContentXml(IContent content);
/// <summary>
/// Used to add/update preview xml for the content item
/// </summary>

View File

@@ -211,6 +211,8 @@ namespace Umbraco.Core.Services
content.CreatorId = userId;
content.WriterId = userId;
repository.AddOrUpdate(content);
//Generate a new preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
uow.Commit();
}
@@ -261,6 +263,8 @@ namespace Umbraco.Core.Services
content.CreatorId = userId;
content.WriterId = userId;
repository.AddOrUpdate(content);
//Generate a new preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
uow.Commit();
}
@@ -785,21 +789,23 @@ namespace Umbraco.Core.Services
/// <param name="raiseEvents">Optional boolean indicating whether or not to raise events.</param>
public void Save(IEnumerable<IContent> contents, int userId = 0, bool raiseEvents = true)
{
var asArray = contents.ToArray();
if (raiseEvents)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(contents), this))
if (Saving.IsRaisedEventCancelled(new SaveEventArgs<IContent>(asArray), this))
return;
}
using (new WriteLock(Locker))
{
var containsNew = contents.Any(x => x.HasIdentity == false);
var containsNew = asArray.Any(x => x.HasIdentity == false);
var uow = _uowProvider.GetUnitOfWork();
using (var repository = _repositoryFactory.CreateContentRepository(uow))
{
if (containsNew)
{
foreach (var content in contents)
foreach (var content in asArray)
{
content.WriterId = userId;
@@ -808,22 +814,26 @@ namespace Umbraco.Core.Services
content.ChangePublishedState(PublishedState.Saved);
repository.AddOrUpdate(content);
uow.Commit();
//add or update preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
}
}
else
{
foreach (var content in contents)
foreach (var content in asArray)
{
content.WriterId = userId;
repository.AddOrUpdate(content);
}
uow.Commit();
//add or update preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
}
}
uow.Commit();
}
if (raiseEvents)
Saved.RaiseEvent(new SaveEventArgs<IContent>(contents, false), this);
Saved.RaiseEvent(new SaveEventArgs<IContent>(asArray, false), this);
Audit.Add(AuditTypes.Save, "Bulk Save content performed by user", userId == -1 ? 0 : userId, -1);
}
@@ -1140,6 +1150,8 @@ namespace Umbraco.Core.Services
copy.WriterId = userId;
repository.AddOrUpdate(copy);
//add or update a preview
repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, c));
uow.Commit();
//Special case for the Upload DataType
@@ -1176,10 +1188,13 @@ namespace Umbraco.Core.Services
if (isUpdated)
{
repository.AddOrUpdate(copy);
//add or update a preview
repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, c));
uow.Commit();
}
}
//TODO: Move this to the repository layer in a single transaction!
//Special case for the Tags DataType
var tagsDataTypeId = new Guid(Constants.PropertyEditors.Tags);
if (content.Properties.Any(x => x.PropertyType.DataTypeId == tagsDataTypeId))
@@ -1193,6 +1208,7 @@ namespace Umbraco.Core.Services
}
//NOTE This 'Relation' part should eventually be delegated to a RelationService
//TODO: This should be party of a single commit
if (relateToOriginal)
{
IRelationType relationType = null;
@@ -1217,14 +1233,15 @@ namespace Umbraco.Core.Services
var children = GetChildren(content.Id);
foreach (var child in children)
{
//TODO: This shouldn't recurse back to this method, it should be done in a private method
// that doesn't have a nested lock and so we can perform the entire operation in one commit.
Copy(child, copy.Id, relateToOriginal, userId);
}
Copied.RaiseEvent(new CopyEventArgs<IContent>(content, copy, false, parentId), this);
Audit.Add(AuditTypes.Copy, "Copy Content performed by user", content.WriterId, content.Id);
//TODO: Don't think we need this here because cache should be cleared by the event listeners
// and the correct ICacheRefreshers!?
RuntimeCacheProvider.Current.Clear();
@@ -1284,6 +1301,8 @@ namespace Umbraco.Core.Services
content.ChangePublishedState(PublishedState.Unpublished);
repository.AddOrUpdate(content);
//add or update a preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
uow.Commit();
}
@@ -1348,8 +1367,7 @@ namespace Umbraco.Core.Services
shouldBeSaved.Add(content);
repository.AddOrUpdate(content);
//Generate a new preview
//add or update a preview
repository.AddOrUpdatePreviewXml(content, c => _entitySerializer.Serialize(this, _dataTypeService, c));
}
@@ -1475,6 +1493,8 @@ namespace Umbraco.Core.Services
//TODO: This is raising events, probably not desirable as this costs performance for event listeners like Examine
Save(content, false, userId);
//TODO: This shouldn't be here! This needs to be part of the repository logic but in order to fix this we need to
// change how this method calls "Save" as it needs to save using an internal method
using (var uow = _uowProvider.GetUnitOfWork())
{
var xml = _entitySerializer.Serialize(this, _dataTypeService, content);
@@ -1655,21 +1675,15 @@ namespace Umbraco.Core.Services
{
item.Result.ContentItem.WriterId = userId;
repository.AddOrUpdate(item.Result.ContentItem);
//add or update a preview
repository.AddOrUpdatePreviewXml(item.Result.ContentItem, c => _entitySerializer.Serialize(this, _dataTypeService, c));
//add or update the published xml
repository.AddOrUpdateContentXml(item.Result.ContentItem, c => _entitySerializer.Serialize(this, _dataTypeService, c));
updated.Add(item.Result.ContentItem);
}
uow.Commit();
foreach (var c in updated)
{
var xml = _entitySerializer.Serialize(this, _dataTypeService, c);
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);
@@ -1700,9 +1714,7 @@ namespace Umbraco.Core.Services
{
content.WriterId = userId;
repository.AddOrUpdate(content);
//Remove 'published' xml from the cmsContentXml table for the unpublished content
uow.Database.Delete<ContentXmlDto>("WHERE nodeId = @Id", new { Id = content.Id });
repository.DeleteContentXml(content);
uow.Commit();
}

View File

@@ -284,6 +284,13 @@ namespace Umbraco.Tests.Services
var content = contentService.GetById(NodeDto.NodeIdSeed + 1);
bool published = contentService.Publish(content, 0);
var provider = new PetaPocoUnitOfWorkProvider();
var uow = provider.GetUnitOfWork();
using (RepositoryResolver.Current.ResolveByType<IContentRepository>(uow))
{
Assert.IsTrue(uow.Database.Exists<ContentXmlDto>(content.Id));
}
// Act
bool unpublished = contentService.UnPublish(content, 0);
@@ -291,6 +298,12 @@ namespace Umbraco.Tests.Services
Assert.That(published, Is.True);
Assert.That(unpublished, Is.True);
Assert.That(content.Published, Is.False);
uow = provider.GetUnitOfWork();
using (RepositoryResolver.Current.ResolveByType<IContentRepository>(uow))
{
Assert.IsFalse(uow.Database.Exists<ContentXmlDto>(content.Id));
}
}
/// <summary>