WIP - commiting what i have. Solved part of the problem but there are others.

This commit is contained in:
Shannon
2019-07-31 18:30:34 +10:00
parent 5c8cd60275
commit 87e7cec02e
20 changed files with 344 additions and 61 deletions

View File

@@ -105,9 +105,14 @@ namespace Umbraco.Core.Persistence.Factories
/// <param name="languageRepository"></param>
/// <param name="edited">out parameter indicating that one or more properties have been edited</param>
/// <param name="editedCultures">out parameter containing a collection of edited cultures when the contentVariation varies by culture</param>
/// <param name="persistedEditedCultures">
/// out parameter containing a collection of edited cultures that are currently persisted in the database which is used to maintain the edited state
/// of each culture value (in cases where variance is being switched)
/// </param>
/// <returns></returns>
public static IEnumerable<PropertyDataDto> BuildDtos(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable<Property> properties,
ILanguageRepository languageRepository, out bool edited, out HashSet<string> editedCultures)
ILanguageRepository languageRepository, out bool edited,
out HashSet<string> editedCultures)
{
var propertyDataDtos = new List<PropertyDataDto>();
edited = false;
@@ -141,14 +146,14 @@ namespace Umbraco.Core.Persistence.Factories
if (propertyValue.EditedValue != null)
propertyDataDtos.Add(BuildDto(currentVersionId, property, languageRepository.GetIdByIsoCode(propertyValue.Culture), propertyValue.Segment, propertyValue.EditedValue));
// property.Values will contain ALL of it's values, both variant and invariant which will be populated if the administrator has previously
// changed the property type to be variant vs invariant.
// We need to check for this scenario here because otherwise the editedCultures and edited flags
// will end up incorrectly so here we need to only process edited cultures based on the
// current value type and how the property varies.
//// property.Values will contain ALL of it's values, both variant and invariant which will be populated if the administrator has previously
//// changed the property type to be variant vs invariant.
//// We need to check for this scenario here because otherwise the editedCultures and edited flags
//// will end up incorrectly so here we need to only process edited cultures based on the
//// current value type and how the property varies.
if (property.PropertyType.VariesByCulture() && isInvariantValue) continue;
if (!property.PropertyType.VariesByCulture() && isCultureValue) continue;
//if (property.PropertyType.VariesByCulture() && isInvariantValue) continue;
//if (!property.PropertyType.VariesByCulture() && isCultureValue) continue;
// use explicit equals here, else object comparison fails at comparing eg strings
var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue);

View File

@@ -18,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// </summary>
internal class ContentTypeRepository : ContentTypeRepositoryBase<IContentType>, IContentTypeRepository
{
public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
: base(scopeAccessor, cache, logger, commonRepository)
public ContentTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
: base(scopeAccessor, cache, logger, commonRepository, languageRepository)
{ }
protected override bool SupportsPublishing => ContentType.SupportsPublishingConst;

View File

@@ -15,6 +15,7 @@ using Umbraco.Core.Persistence.Factories;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Scoping;
using Umbraco.Core.Services;
using static Umbraco.Core.Persistence.NPocoSqlExtensions.Statics;
namespace Umbraco.Core.Persistence.Repositories.Implement
{
@@ -26,14 +27,15 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
internal abstract class ContentTypeRepositoryBase<TEntity> : NPocoRepositoryBase<int, TEntity>, IReadRepository<Guid, TEntity>
where TEntity : class, IContentTypeComposition
{
protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
: base(scopeAccessor, cache, logger)
{
CommonRepository = commonRepository;
LanguageRepository = languageRepository;
}
protected IContentTypeCommonRepository CommonRepository { get; }
protected ILanguageRepository LanguageRepository { get; }
protected abstract bool SupportsPublishing { get; }
public IEnumerable<MoveEventInfo<TEntity>> Move(TEntity moving, EntityContainer container)
@@ -646,10 +648,16 @@ AND umbracoNode.id <> @id",
case ContentVariation.Culture:
CopyPropertyData(null, defaultLanguageId, propertyTypeIds, impactedL);
CopyTagData(null, defaultLanguageId, propertyTypeIds, impactedL);
RenormalizeDocumentCultureVariations(propertyTypeIds, impactedL);
//TODO: Here we need to normalize the umbracoDocumentCultureVariation table for it's edited flags which are calculated based
//on changed property or name values
break;
case ContentVariation.Nothing:
CopyPropertyData(defaultLanguageId, null, propertyTypeIds, impactedL);
CopyTagData(defaultLanguageId, null, propertyTypeIds, impactedL);
RenormalizeDocumentCultureVariations(propertyTypeIds, impactedL);
//TODO: Here we need to normalize the umbracoDocumentCultureVariation table for it's edited flags which are calculated based
//on changed property or name values
break;
case ContentVariation.CultureAndSegment:
case ContentVariation.Segment:
@@ -659,6 +667,55 @@ AND umbracoNode.id <> @id",
}
}
//private HashSet<string> GetEditedCultures(ContentVariation contentVariation, int currentVersionId, int publishedVersionId, IEnumerable<PropertyDataDto> properties)
//{
// HashSet<string> editedCultures = null; // don't allocate unless necessary
// string defaultCulture = null; //don't allocate unless necessary
// var entityVariesByCulture = contentVariation.VariesByCulture();
// // create dtos for each property values, but only for values that do actually exist
// // ie have a non-null value, everything else is just ignored and won't have a db row
// foreach (var property in properties)
// {
// if (property.PropertyType.SupportsPublishing)
// {
// //create the resulting hashset if it's not created and the entity varies by culture
// if (entityVariesByCulture && editedCultures == null)
// editedCultures = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
// // publishing = deal with edit and published values
// foreach (var propertyValue in property.Values)
// {
// var isInvariantValue = propertyValue.Culture == null;
// var isCultureValue = propertyValue.Culture != null && propertyValue.Segment == null;
// // use explicit equals here, else object comparison fails at comparing eg strings
// var sameValues = propertyValue.PublishedValue == null ? propertyValue.EditedValue == null : propertyValue.PublishedValue.Equals(propertyValue.EditedValue);
// if (entityVariesByCulture && !sameValues)
// {
// if (isCultureValue)
// {
// editedCultures.Add(propertyValue.Culture); // report culture as edited
// }
// else if (isInvariantValue)
// {
// // flag culture as edited if it contains an edited invariant property
// if (defaultCulture == null)
// defaultCulture = languageRepository.GetDefaultIsoCode();
// editedCultures.Add(defaultCulture);
// }
// }
// }
// }
// }
// return editedCultures;
//}
/// <summary>
/// Moves variant data for a content type variation change.
/// </summary>
@@ -963,6 +1020,208 @@ AND umbracoNode.id <> @id",
Database.Execute(sqlDelete);
}
}
/// <summary>
/// Re-normalizes the edited value in the umbracoDocumentCultureVariation table when property variations are changed
/// </summary>
/// <param name="propertyTypeIds"></param>
/// <param name="contentTypeIds"></param>
/// <remarks>
/// If this is not done, then in some cases the "edited" value for a particular culture for a document will remain true when it should be false
/// if the property was changed to invariant. In order to do this we need to recalculate this value based on the values stored for each
/// property, culture and current/published version. The end result is to update the edited value in the umbracoDocumentCultureVariation table so we
/// make sure to join this table with the lookups so that only relevant data is returned.
/// </remarks>
private void RenormalizeDocumentCultureVariations(IReadOnlyCollection<int> propertyTypeIds, IReadOnlyCollection<int> contentTypeIds = null)
{
var defaultLang = LanguageRepository.GetDefaultId();
//This will build up a query to get the property values of both the current and the published version so that we can check
//based on the current variance of each item to see if it's 'edited' value should be true/false.
var whereInArgsCount = propertyTypeIds.Count + (contentTypeIds?.Count ?? 0);
if (whereInArgsCount > 2000)
throw new NotSupportedException("Too many property/content types.");
var propertySql = Sql()
.Select<PropertyDataDto>()
.AndSelect<ContentVersionDto>(x => x.NodeId, x => x.Current)
.AndSelect<DocumentVersionDto>(x => x.Published)
.AndSelect<PropertyTypeDto>(x => x.Variations)
.From<PropertyDataDto>()
.InnerJoin<ContentVersionDto>().On<ContentVersionDto, PropertyDataDto>((left, right) => left.Id == right.VersionId)
.InnerJoin<PropertyTypeDto>().On<PropertyTypeDto, PropertyDataDto>((left, right) => left.Id == right.PropertyTypeId);
if (contentTypeIds != null)
{
propertySql.InnerJoin<ContentDto>().On<ContentDto, ContentVersionDto>((c, cversion) => c.NodeId == cversion.NodeId);
}
propertySql.LeftJoin<DocumentVersionDto>().On<DocumentVersionDto, ContentVersionDto>((docversion, cversion) => cversion.Id == docversion.Id)
.Where<DocumentVersionDto, ContentVersionDto>((docversion, cversion) => cversion.Current || docversion.Published)
.WhereIn<PropertyDataDto>(x => x.PropertyTypeId, propertyTypeIds);
if (contentTypeIds != null)
{
propertySql.WhereIn<ContentDto>(x => x.ContentTypeId, contentTypeIds);
}
propertySql
.OrderBy<ContentVersionDto>(x => x.NodeId)
.OrderBy<PropertyDataDto>(x => x.PropertyTypeId, x => x.LanguageId, x => x.VersionId);
//keep track of this node/lang to mark or unmark as edited
var editedVersions = new Dictionary<(int nodeId, int? langId), bool>();
var nodeId = -1;
var propertyTypeId = -1;
PropertyValueVersionDto pubRow = null;
//This is a QUERY we are not fetching this all into memory so we cannot make any changes during this iteration, we are just collecting data.
//Published data will always come before Current data based on the version id sort.
//There will only be one published row (max) and one current row per property.
foreach (var row in Database.Query<PropertyValueVersionDto>(propertySql))
{
//make sure to reset on each node/property change
if (nodeId != row.NodeId || propertyTypeId != row.PropertyTypeId)
{
nodeId = row.NodeId;
propertyTypeId = row.PropertyTypeId;
pubRow = null;
}
if (row.Published)
pubRow = row;
if (row.Current)
{
var propVariations = (ContentVariation)row.Variations;
//if this prop doesn't vary but the row has a lang assigned or vice versa, flag this as not edited
if (!propVariations.VariesByCulture() && row.LanguageId.HasValue
|| propVariations.VariesByCulture() && !row.LanguageId.HasValue)
{
//Flag this as not edited for this node/lang if the key doesn't exist
if (!editedVersions.TryGetValue((row.NodeId, row.LanguageId), out _))
editedVersions.Add((row.NodeId, row.LanguageId), false);
}
else if (pubRow == null)
{
//this would mean that that this property is 'edited' since there is no published version
editedVersions.Add((row.NodeId, row.LanguageId), true);
}
//compare the property values, if they differ from versions then flag the current version as edited
else if (IsPropertyValueChanged(pubRow, row))
{
//Here we would check if the property is invariant, in which case the edited language should be indicated by the default lang
editedVersions[(row.NodeId, !propVariations.VariesByCulture() ? defaultLang : row.LanguageId)] = true;
}
//reset
pubRow = null;
}
}
//lookup all matching rows in umbracoDocumentCultureVariation
var docCultureVariationsToUpdate = Database.Fetch<DocumentCultureVariationDto>(
Sql().Select<DocumentCultureVariationDto>().From<DocumentCultureVariationDto>()
.WhereIn<DocumentCultureVariationDto>(x => x.LanguageId, editedVersions.Keys.Select(x => x.langId).ToList())
.WhereIn<DocumentCultureVariationDto>(x => x.NodeId, editedVersions.Keys.Select(x => x.nodeId)))
//convert to dictionary with the same key type
.ToDictionary(x => (x.NodeId, (int?)x.LanguageId), x => x);
foreach (var ev in editedVersions)
{
if (docCultureVariationsToUpdate.TryGetValue(ev.Key, out var docVariations))
{
//check if it needs updating
if (docVariations.Edited != ev.Value)
{
docVariations.Edited = ev.Value;
Database.Update(docVariations);
}
}
else
{
//the row doesn't exist but needs creating
//TODO: Does this ever happen?? Need to see if we can test this
}
}
////Generate SQL to lookup the current name vs the publish name for each language
//var nameSql = Sql()
// .Select<ContentVersionDto>("cv1", x => x.NodeId, x => Alias(x.Id, "currentVersion"))
// .AndSelect<ContentVersionCultureVariationDto>("cvcv1", x => x.LanguageId, x => Alias(x.Name, "currentName"))
// .AndSelect<ContentVersionCultureVariationDto>("cvcv2", x => Alias(x.Name, "publishedName"))
// .AndSelect<DocumentVersionDto>("dv", x => Alias(x.Id, "publishedVersion"))
// .AndSelect<DocumentCultureVariationDto>("dcv", x => x.Id, x => x.Edited)
// .From<ContentVersionCultureVariationDto>("cvcv1")
// .InnerJoin<ContentVersionDto>("cv1")
// .On<ContentVersionDto, ContentVersionCultureVariationDto>((left, right) => left.Id == right.VersionId, "cv1", "cvcv1")
// .InnerJoin<DocumentCultureVariationDto>("dcv")
// .On<DocumentCultureVariationDto, ContentVersionDto, ContentVersionCultureVariationDto>((left, right, other) => left.NodeId == right.NodeId && left.LanguageId == other.LanguageId, "dcv", "cv1", "cvcv1")
// .LeftJoin<ContentVersionDto>(nested =>
// nested.InnerJoin<DocumentVersionDto>("dv")
// .On<ContentVersionDto, DocumentVersionDto>((left, right) => left.Id == right.Id && right.Published, "cv2", "dv"), "cv2")
// .On<ContentVersionDto, ContentVersionDto>((left, right) => left.NodeId == right.NodeId, "cv1", "cv2")
// .LeftJoin<ContentVersionCultureVariationDto>("cvcv2")
// .On<ContentVersionCultureVariationDto, ContentVersionDto, ContentVersionCultureVariationDto>((left, right, other) => left.VersionId == right.Id && left.LanguageId == other.LanguageId, "cvcv2", "cv2", "cvcv1")
// .Where<ContentVersionDto>(x => x.Current, "cv1")
// .OrderBy("cv1.nodeId, cvcv1.versionId, cvcv1.languageId");
//var names = Database.Fetch<NameCompareDto>(nameSql);
}
private static bool IsPropertyValueChanged(PropertyValueVersionDto pubRow, PropertyValueVersionDto row)
{
return !pubRow.TextValue.IsNullOrWhiteSpace() && pubRow.TextValue != row.TextValue
|| !pubRow.VarcharValue.IsNullOrWhiteSpace() && pubRow.VarcharValue != row.VarcharValue
|| pubRow.DateValue.HasValue && pubRow.DateValue != row.DateValue
|| pubRow.DecimalValue.HasValue && pubRow.DecimalValue != row.DecimalValue
|| pubRow.IntValue.HasValue && pubRow.IntValue != row.IntValue;
}
private class NameCompareDto
{
public int NodeId { get; set; }
public int CurrentVersion { get; set; }
public int LanguageId { get; set; }
public string CurrentName { get; set; }
public string PublishedName { get; set; }
public int? PublishedVersion { get; set; }
public int Id { get; set; } // the Id of the DocumentCultureVariationDto
public bool Edited { get; set; }
}
private class PropertyValueVersionDto
{
public int VersionId { get; set; }
public int PropertyTypeId { get; set; }
public int? LanguageId { get; set; }
public string Segment { get; set; }
public int? IntValue { get; set; }
private decimal? _decimalValue;
[Column("decimalValue")]
public decimal? DecimalValue
{
get => _decimalValue;
set => _decimalValue = value?.Normalize();
}
public DateTime? DateValue { get; set; }
public string VarcharValue { get; set; }
public string TextValue { get; set; }
public int NodeId { get; set; }
public bool Current { get; set; }
public bool Published { get; set; }
public byte Variations { get; set; }
}
private void DeletePropertyType(int contentTypeId, int propertyTypeId)

View File

@@ -386,7 +386,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
// insert document variations
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, editedCultures));
}
// refresh content
@@ -571,7 +571,7 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
Database.BulkInsertRecords(GetContentVariationDtos(entity, publishing));
// insert document variations
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, publishing, editedCultures));
Database.BulkInsertRecords(GetDocumentVariationDtos(entity, editedCultures));
}
// refresh content
@@ -1297,25 +1297,30 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
};
}
private IEnumerable<DocumentCultureVariationDto> GetDocumentVariationDtos(IContent content, bool publishing, HashSet<string> editedCultures)
private IEnumerable<DocumentCultureVariationDto> GetDocumentVariationDtos(IContent content, HashSet<string> editedCultures)
{
var allCultures = content.AvailableCultures.Union(content.PublishedCultures); // union = distinct
foreach (var culture in allCultures)
yield return new DocumentCultureVariationDto
{
var dto = new DocumentCultureVariationDto
{
NodeId = content.Id,
LanguageId = LanguageRepository.GetIdByIsoCode(culture) ?? throw new InvalidOperationException("Not a valid culture."),
Culture = culture,
Name = content.GetCultureName(culture) ?? content.GetPublishName(culture),
// note: can't use IsCultureEdited at that point - hasn't been updated yet - see PersistUpdatedItem
Available = content.IsCultureAvailable(culture),
Published = content.IsCulturePublished(culture),
Edited = content.IsCultureAvailable(culture) &&
(!content.IsCulturePublished(culture) || (editedCultures != null && editedCultures.Contains(culture)))
Published = content.IsCulturePublished(culture)
};
// note: can't use IsCultureEdited at that point - hasn't been updated yet - see PersistUpdatedItem
dto.Edited = content.IsCultureAvailable(culture) &&
(!content.IsCulturePublished(culture) || (editedCultures != null && editedCultures.Contains(culture)));
yield return dto;
}
}
private class ContentVariation

View File

@@ -17,8 +17,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// </summary>
internal class MediaTypeRepository : ContentTypeRepositoryBase<IMediaType>, IMediaTypeRepository
{
public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
: base(scopeAccessor, cache, logger, commonRepository)
public MediaTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
: base(scopeAccessor, cache, logger, commonRepository, languageRepository)
{ }
protected override bool SupportsPublishing => MediaType.SupportsPublishingConst;

View File

@@ -18,8 +18,8 @@ namespace Umbraco.Core.Persistence.Repositories.Implement
/// </summary>
internal class MemberTypeRepository : ContentTypeRepositoryBase<IMemberType>, IMemberTypeRepository
{
public MemberTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository)
: base(scopeAccessor, cache, logger, commonRepository)
public MemberTypeRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IContentTypeCommonRepository commonRepository, ILanguageRepository languageRepository)
: base(scopeAccessor, cache, logger, commonRepository, languageRepository)
{ }
protected override bool SupportsPublishing => MemberType.SupportsPublishingConst;

View File

@@ -29,10 +29,11 @@ namespace Umbraco.Tests.Persistence.Repositories
private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out ContentTypeRepository contentTypeRepository)
{
var langRepository = new LanguageRepository(scopeAccessor, AppCaches.Disabled, Logger);
var templateRepository = new TemplateRepository(scopeAccessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(scopeAccessor, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, AppCaches.Disabled);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository, langRepository);
var languageRepository = new LanguageRepository(scopeAccessor, AppCaches.Disabled, Logger);
var repository = new DocumentRepository(scopeAccessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
@@ -40,9 +41,10 @@ namespace Umbraco.Tests.Persistence.Repositories
private ContentTypeRepository CreateRepository(IScopeAccessor scopeAccessor)
{
var langRepository = new LanguageRepository(scopeAccessor, AppCaches.Disabled, Logger);
var templateRepository = new TemplateRepository(scopeAccessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, AppCaches.Disabled);
var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository);
var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository, langRepository);
return contentTypeRepository;
}
@@ -50,7 +52,8 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var templateRepository = new TemplateRepository(scopeAccessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, AppCaches.Disabled);
var contentTypeRepository = new MediaTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository);
var langRepository = new LanguageRepository(scopeAccessor, AppCaches.Disabled, Logger);
var contentTypeRepository = new MediaTypeRepository(scopeAccessor, AppCaches.Disabled, Logger, commonRepository, langRepository);
return contentTypeRepository;
}

View File

@@ -67,8 +67,8 @@ namespace Umbraco.Tests.Persistence.Repositories
templateRepository = new TemplateRepository(scopeAccessor, appCaches, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger);
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, commonRepository);
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository(scopeAccessor, appCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}

View File

@@ -23,8 +23,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var templateRepository = new TemplateRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, commonRepository);
languageRepository = new LanguageRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, commonRepository, languageRepository);
documentRepository = new DocumentRepository(accessor, Core.Cache.AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
var domainRepository = new DomainRepository(accessor, Core.Cache.AppCaches.Disabled, Logger);
return domainRepository;

View File

@@ -38,7 +38,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var templateRepository = new TemplateRepository(scopeAccessor, appCaches, Logger, TestObjects.GetFileSystemsMock());
var commonRepository = new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches);
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger, commonRepository);
var languageRepository = new LanguageRepository(scopeAccessor, appCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, Logger, commonRepository, languageRepository);
var tagRepository = new TagRepository(scopeAccessor, appCaches, Logger);
var repository = new MediaRepository(scopeAccessor, appCaches, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>());
return repository;

View File

@@ -23,7 +23,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var cacheHelper = AppCaches.Disabled;
var templateRepository = new TemplateRepository((IScopeAccessor)provider, cacheHelper, Logger, TestObjects.GetFileSystemsMock());
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository, AppCaches);
return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches, Logger);
return new MediaTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
}
private EntityContainerRepository CreateContainerRepository(IScopeProvider provider)

View File

@@ -31,7 +31,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var accessor = (IScopeAccessor) provider;
var templateRepository = Mock.Of<ITemplateRepository>();
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
memberTypeRepository = new MemberTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
memberGroupRepository = new MemberGroupRepository(accessor, AppCaches.Disabled, Logger);
var tagRepo = new TagRepository(accessor, AppCaches.Disabled, Logger);
var repository = new MemberRepository(accessor, AppCaches.Disabled, Logger, memberTypeRepository, memberGroupRepository, tagRepo, Mock.Of<ILanguageRepository>());

View File

@@ -24,7 +24,8 @@ namespace Umbraco.Tests.Persistence.Repositories
{
var templateRepository = Mock.Of<ITemplateRepository>();
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, templateRepository, AppCaches);
return new MemberTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Mock.Of<ILogger>(), commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Mock.Of<ILogger>());
return new MemberTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Mock.Of<ILogger>(), commonRepository, languageRepository);
}
[Test]

View File

@@ -308,8 +308,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var templateRepository = new TemplateRepository(accessor, AppCaches, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, AppCaches, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}

View File

@@ -956,8 +956,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}
@@ -968,7 +968,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches.Disabled);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new MediaRepository(accessor, AppCaches.Disabled, Logger, mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>());
return repository;
}

View File

@@ -239,8 +239,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var tagRepository = new TagRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(ScopeProvider, templateRepository, AppCaches);
var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger);
var contentTypeRepository = new ContentTypeRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var contentRepo = new DocumentRepository((IScopeAccessor) ScopeProvider, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage2", "Textpage");

View File

@@ -26,7 +26,8 @@ namespace Umbraco.Tests.Persistence.Repositories
var accessor = (IScopeAccessor) provider;
var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of<ILogger>(), commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
mediaTypeRepository = new MediaTypeRepository(accessor, AppCaches, Mock.Of<ILogger>(), commonRepository, languageRepository);
var tagRepository = new TagRepository(accessor, AppCaches, Mock.Of<ILogger>());
var repository = new MediaRepository(accessor, AppCaches, Mock.Of<ILogger>(), mediaTypeRepository, tagRepository, Mock.Of<ILanguageRepository>());
return repository;
@@ -44,8 +45,8 @@ namespace Umbraco.Tests.Persistence.Repositories
templateRepository = new TemplateRepository(accessor, AppCaches, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, AppCaches, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository(accessor, AppCaches, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}

View File

@@ -166,8 +166,8 @@ namespace Umbraco.Tests.Services
var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
@@ -200,8 +200,8 @@ namespace Umbraco.Tests.Services
var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
@@ -232,8 +232,8 @@ namespace Umbraco.Tests.Services
var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor) provider, tRepository, AppCaches);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act
@@ -267,8 +267,8 @@ namespace Umbraco.Tests.Services
var tRepository = new TemplateRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepo = new TagRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository((IScopeAccessor)provider, tRepository, AppCaches);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger);
var languageRepository = new LanguageRepository((IScopeAccessor)provider, AppCaches.Disabled, Logger);
var ctRepository = new ContentTypeRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository((IScopeAccessor) provider, AppCaches.Disabled, Logger, ctRepository, tRepository, tagRepo, languageRepository);
// Act

View File

@@ -3008,8 +3008,8 @@ namespace Umbraco.Tests.Services
var templateRepository = new TemplateRepository(accessor, AppCaches.Disabled, Logger, TestObjects.GetFileSystemsMock());
var tagRepository = new TagRepository(accessor, AppCaches.Disabled, Logger);
var commonRepository = new ContentTypeCommonRepository(accessor, templateRepository, AppCaches);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository);
var languageRepository = new LanguageRepository(accessor, AppCaches.Disabled, Logger);
contentTypeRepository = new ContentTypeRepository(accessor, AppCaches.Disabled, Logger, commonRepository, languageRepository);
var repository = new DocumentRepository(accessor, AppCaches.Disabled, Logger, contentTypeRepository, templateRepository, tagRepository, languageRepository);
return repository;
}

View File

@@ -810,12 +810,18 @@ namespace Umbraco.Tests.Services
var document = (IContent)new Content("document", -1, contentType);
document.SetCultureName("doc1en", "en");
document.SetCultureName("doc1fr", "fr");
document.SetValue("value1", "v1en", "en");
document.SetValue("value1", "v1fr", "fr");
ServiceContext.ContentService.Save(document);
document.SetValue("value1", "v1en-init", "en");
document.SetValue("value1", "v1fr-init", "fr");
ServiceContext.ContentService.SaveAndPublish(document); //all values are published which means the document is not 'edited'
//at this stage there will be 4 property values stored in the DB for "value1" against "en" and "fr" for both edited/published versions,
//for the published values, these will be null
document = ServiceContext.ContentService.GetById(document.Id);
Assert.IsFalse(document.IsCultureEdited("en"));
Assert.IsFalse(document.IsCultureEdited("fr"));
Assert.IsFalse(document.Edited);
document.SetValue("value1", "v1en", "en"); //change the property culture value, so now this culture will be edited
document.SetValue("value1", "v1fr", "fr"); //change the property culture value, so now this culture will be edited
ServiceContext.ContentService.Save(document);
document = ServiceContext.ContentService.GetById(document.Id);
Assert.AreEqual("doc1en", document.Name);
@@ -829,18 +835,17 @@ namespace Umbraco.Tests.Services
// switch property type to Nothing
contentType.PropertyTypes.First(x => x.Alias == "value1").Variations = ContentVariation.Nothing;
ServiceContext.ContentTypeService.Save(contentType);
ServiceContext.ContentTypeService.Save(contentType); //This is going to have to re-normalize the "Edited" flag
document = ServiceContext.ContentService.GetById(document.Id);
Assert.IsTrue(document.IsCultureEdited("en")); //This will remain true because there is now a pending change for the invariant property data which is flagged under the default lang
Assert.IsFalse(document.IsCultureEdited("fr")); //This will be false because nothing has changed for this culture and the property no longer reflects variant changes
Assert.IsTrue(document.Edited);
// publish the document
document.SetValue("value1", "v1inv"); //update the invariant value
//update the invariant value and publish
document.SetValue("value1", "v1inv");
ServiceContext.ContentService.SaveAndPublish(document);
//at this stage there will be 6 property values stored in the DB for "value1" against "en", "fr" and null for both edited/published versions,
//for the published values for the cultures, these will still be null but the invariant edited/published values will both be "v1inv".
document = ServiceContext.ContentService.GetById(document.Id);
Assert.AreEqual("doc1en", document.Name);
Assert.AreEqual("doc1en", document.GetCultureName("en"));
@@ -848,8 +853,8 @@ namespace Umbraco.Tests.Services
Assert.IsNull(document.GetValue("value1", "en")); //The values are there but the business logic returns null
Assert.IsNull(document.GetValue("value1", "fr")); //The values are there but the business logic returns null
Assert.AreEqual("v1inv", document.GetValue("value1"));
Assert.IsFalse(document.IsCultureEdited("en")); //This returns false, the culture shouldn't be marked as edited because the invariant property value is published
Assert.IsFalse(document.IsCultureEdited("fr")); //This returns false, the culture shouldn't be marked as edited because the invariant property value is published
Assert.IsFalse(document.IsCultureEdited("en")); //This returns false, everything is published - however in the DB this is not the case for the "en" version of the property
Assert.IsFalse(document.IsCultureEdited("fr")); //This returns false, everything is published
Assert.IsFalse(document.Edited);
// switch property back to Culture