This commit is contained in:
Sebastiaan Janssen
2013-01-08 11:48:04 -01:00
8 changed files with 166 additions and 14 deletions

View File

@@ -72,6 +72,12 @@ namespace Umbraco.Core.Models
/// <param name="template">Default <see cref="ITemplate"/></param>
public void SetDefaultTemplate(ITemplate template)
{
if (template == null)
{
DefaultTemplateId = 0;
return;
}
DefaultTemplateId = template.Id;
if(_allowedTemplates.Any(x => x != null && x.Id == template.Id) == false)
{

View File

@@ -2,6 +2,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Runtime.Caching;
using System.Threading;
using Umbraco.Core.Models.EntityBase;
namespace Umbraco.Core.Persistence.Caching
@@ -23,9 +24,10 @@ namespace Umbraco.Core.Persistence.Caching
#endregion
private readonly ObjectCache _memoryCache = new MemoryCache("in-memory");
//TODO Save this in cache as well, so its not limited to a single server usage
private ConcurrentDictionary<string, string> _keyTracker = new ConcurrentDictionary<string, string>();
private ObjectCache _memoryCache = new MemoryCache("in-memory");
private static readonly ReaderWriterLockSlim ClearLock = new ReaderWriterLockSlim();
public IEntity GetById(Type type, Guid id)
{
@@ -77,6 +79,16 @@ namespace Umbraco.Core.Persistence.Caching
_keyTracker.TryRemove(key, out throwaway);
}
public void Clear()
{
using (new ReadLock(ClearLock))
{
_keyTracker.Clear();
_memoryCache.DisposeIfDisposable();
_memoryCache = new MemoryCache("in-memory");
}
}
private string GetCompositeId(Type type, Guid id)
{
return string.Format("{0}-{1}", type.Name, id.ToString());

View File

@@ -365,6 +365,8 @@ namespace Umbraco.Core.Persistence.Repositories
{
foreach (var property in entity.Properties)
{
if(keyDictionary.ContainsKey(property.PropertyTypeId) == false) continue;
property.Id = keyDictionary[property.PropertyTypeId];
}
}

View File

@@ -168,11 +168,19 @@ namespace Umbraco.Core.Persistence.Repositories
if (((ICanBeDirty)entity).IsPropertyDirty("PropertyGroups") || entity.PropertyGroups.Any(x => x.IsDirty()))
{
//Delete PropertyTypes by excepting entries from db with entries from collections
var dbPropertyTypes = Database.Fetch<PropertyTypeDto>("WHERE contentTypeId = @Id", new { Id = entity.Id }).Select(x => x.Alias);
var entityPropertyTypes = entity.PropertyTypes.Select(x => x.Alias);
var aliases = dbPropertyTypes.Except(entityPropertyTypes);
var dbPropertyTypes = Database.Fetch<PropertyTypeDto>("WHERE contentTypeId = @Id", new { Id = entity.Id });
var dbPropertyTypeAlias = dbPropertyTypes.Select(x => x.Alias.ToLowerInvariant());
var entityPropertyTypes = entity.PropertyTypes.Select(x => x.Alias.ToLowerInvariant());
var aliases = dbPropertyTypeAlias.Except(entityPropertyTypes);
foreach (var alias in aliases)
{
//Before a PropertyType can be deleted, all Properties based on that PropertyType should be deleted.
var propertyType = dbPropertyTypes.FirstOrDefault(x => x.Alias.ToLowerInvariant() == alias);
if (propertyType != null)
{
Database.Delete<PropertyDataDto>("WHERE propertytypeid = @Id", new { Id = propertyType.Id });
}
Database.Delete<PropertyTypeDto>("WHERE contentTypeId = @Id AND Alias = @Alias", new { Id = entity.Id, Alias = alias });
}
//Delete Tabs/Groups by excepting entries from db with entries from collections

View File

@@ -270,6 +270,128 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.That(updated.AllowedContentTypes.Any(x => x.Alias == simpleSubpageContentType.Alias), Is.True);
}
[Test]
public void Can_Verify_Removal_Of_Used_PropertyType_From_ContentType()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = RepositoryResolver.Current.ResolveByType<IContentTypeRepository>(unitOfWork);
var contentRepository = RepositoryResolver.Current.ResolveByType<IContentRepository>(unitOfWork);
var contentType = repository.Get(1046);
var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id);
contentRepository.AddOrUpdate(subpage);
unitOfWork.Commit();
// Act
contentType.RemovePropertyType("keywords");
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
// Assert
Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(3));
Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "keywords"), Is.False);
Assert.That(subpage.Properties.First(x => x.Alias == "metaDescription").Value, Is.EqualTo("This is the meta description for a textpage"));
}
[Test]
public void Can_Verify_Addition_Of_PropertyType_After_ContentType_Is_Used()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = RepositoryResolver.Current.ResolveByType<IContentTypeRepository>(unitOfWork);
var contentRepository = RepositoryResolver.Current.ResolveByType<IContentRepository>(unitOfWork);
var contentType = repository.Get(1046);
var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id);
contentRepository.AddOrUpdate(subpage);
unitOfWork.Commit();
// Act
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
// Assert
Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(5));
Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "metaAuthor"), Is.True);
}
[Test]
public void Can_Verify_Usage_Of_New_PropertyType_On_Content()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = RepositoryResolver.Current.ResolveByType<IContentTypeRepository>(unitOfWork);
var contentRepository = RepositoryResolver.Current.ResolveByType<IContentRepository>(unitOfWork);
var contentType = repository.Get(1046);
var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id);
contentRepository.AddOrUpdate(subpage);
unitOfWork.Commit();
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
// Act
var content = contentRepository.Get(subpage.Id);
content.SetValue("metaAuthor", "John Doe");
contentRepository.AddOrUpdate(content);
unitOfWork.Commit();
//Assert
var updated = contentRepository.Get(subpage.Id);
Assert.That(updated.GetValue("metaAuthor").ToString(), Is.EqualTo("John Doe"));
Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(5));
Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "metaAuthor"), Is.True);
}
[Test]
public void
Can_Verify_That_A_Combination_Of_Adding_And_Deleting_PropertyTypes_Doesnt_Cause_Issues_For_Content_And_ContentType
()
{
// Arrange
var provider = new PetaPocoUnitOfWorkProvider();
var unitOfWork = provider.GetUnitOfWork();
var repository = RepositoryResolver.Current.ResolveByType<IContentTypeRepository>(unitOfWork);
var contentRepository = RepositoryResolver.Current.ResolveByType<IContentRepository>(unitOfWork);
var contentType = repository.Get(1046);
var subpage = MockedContent.CreateTextpageContent(contentType, "Text Page 1", contentType.Id);
contentRepository.AddOrUpdate(subpage);
unitOfWork.Commit();
//Remove PropertyType
contentType.RemovePropertyType("keywords");
//Add PropertyType
var propertyGroup = contentType.PropertyGroups.First(x => x.Name == "Meta");
propertyGroup.PropertyTypes.Add(new PropertyType(new Guid(), DataTypeDatabaseType.Ntext) { Alias = "metaAuthor", Name = "Meta Author", Description = "", HelpText = "", Mandatory = false, SortOrder = 1, DataTypeDefinitionId = -88 });
repository.AddOrUpdate(contentType);
unitOfWork.Commit();
// Act
var content = contentRepository.Get(subpage.Id);
content.SetValue("metaAuthor", "John Doe");
contentRepository.AddOrUpdate(content);
unitOfWork.Commit();
//Assert
var updated = contentRepository.Get(subpage.Id);
Assert.That(updated.GetValue("metaAuthor").ToString(), Is.EqualTo("John Doe"));
Assert.That(updated.Properties.First(x => x.Alias == "metaDescription").Value, Is.EqualTo("This is the meta description for a textpage"));
Assert.That(contentType.PropertyTypes.Count(), Is.EqualTo(4));
Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "metaAuthor"), Is.True);
Assert.That(contentType.PropertyTypes.Any(x => x.Alias == "keywords"), Is.False);
}
public void CreateTestData()
{
//Create and Save ContentType "umbTextpage" -> 1045

View File

@@ -128,6 +128,8 @@ namespace umbraco.settings
else
dt.RemoveDefaultTemplate();
dt.Save();
bindTemplates();
}
else

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;
using Umbraco.Core.Persistence.Caching;
using umbraco.BusinessLogic;
using umbraco.cms.businesslogic.cache;
using umbraco.cms.businesslogic.datatype;
@@ -461,10 +462,10 @@ namespace umbraco.cms.businesslogic.propertytype
// clear cache in contentype
Cache.ClearCacheItem("ContentType_PropertyTypes_Content:" + _contenttypeid);
// clear cache in tab
// zb-00040 #29889 : clear the right cache! t.ContentType is the ctype which _defines_ the tab, not the current one.
// foreach (ContentType.TabI t in new ContentType(ContentTypeId).getVirtualTabs)
// ContentType.FlushTabCache(t.Id, ContentTypeId);
//Ensure that DocumentTypes are reloaded from db by clearing cache - this similar to the Save method on DocumentType.
//NOTE Would be nice if we could clear cache by type instead of emptying the entire cache.
InMemoryCacheProvider.Current.Clear();
RuntimeCacheProvider.Current.Clear();
}
public static PropertyType GetPropertyType(int id)

View File

@@ -420,14 +420,11 @@ namespace umbraco.cms.businesslogic.web
return doc;
}
[Obsolete("Deprecated, Use RemoveTemplate() on Umbraco.Core.Models.ContentType", false)]
[Obsolete("Deprecated, Use SetDefaultTemplate(null) on Umbraco.Core.Models.ContentType", false)]
public void RemoveDefaultTemplate()
{
_defaultTemplate = 0;
var template = _contentType.DefaultTemplate;
if(template != null)
_contentType.RemoveTemplate(template);
_contentType.SetDefaultTemplate(null);
}
public bool HasTemplate()
@@ -457,8 +454,10 @@ namespace umbraco.cms.businesslogic.web
ApplicationContext.Current.Services.ContentTypeService.Save(_contentType);
//Ensure that DocumentTypes are reloaded from db by clearing cache
//Ensure that DocumentTypes are reloaded from db by clearing cache.
//NOTE Would be nice if we could clear cache by type instead of emptying the entire cache.
InMemoryCacheProvider.Current.Clear();
RuntimeCacheProvider.Current.Clear();//Runtime cache is used for Content, so we clear that as well
base.Save();
FireAfterSave(e);