# Conflicts: # src/Umbraco.Core/Models/PublishedContent/IPublishedContent.cs # src/Umbraco.Core/Models/PublishedContent/PublishedContentBase.cs # src/Umbraco.Core/Models/PublishedContent/PublishedContentWrapped.cs # src/Umbraco.Core/Packaging/ConflictingPackageData.cs # src/Umbraco.Core/Packaging/PackagesRepository.cs # src/Umbraco.Core/PublishedCache/PublishedMember.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MacroRepository.cs # src/Umbraco.Infrastructure/PropertyEditors/RichTextEditorPastedImages.cs # src/Umbraco.PublishedCache.NuCache/PublishedContent.cs # src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs # src/Umbraco.Tests/PublishedContent/SolidPublishedSnapshot.cs # src/Umbraco.Web/Macros/PublishedContentHashtableConverter.cs # src/Umbraco.Web/PublishedContentExtensions.cs # src/Umbraco.Web/Trees/MediaTypeTreeController.cs
223 lines
7.7 KiB
C#
223 lines
7.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using NPoco;
|
|
using Umbraco.Core.Cache;
|
|
using Umbraco.Core.Logging;
|
|
using Umbraco.Core.Models;
|
|
using Umbraco.Core.Models.Entities;
|
|
using Umbraco.Core.Persistence.Dtos;
|
|
using Umbraco.Core.Persistence.Factories;
|
|
using Umbraco.Core.Persistence.Querying;
|
|
using Umbraco.Core.Scoping;
|
|
using Umbraco.Core.Strings;
|
|
|
|
namespace Umbraco.Core.Persistence.Repositories.Implement
|
|
{
|
|
internal class MacroRepository : NPocoRepositoryBase<int, IMacro>, IMacroRepository
|
|
{
|
|
private readonly IShortStringHelper _shortStringHelper;
|
|
|
|
public MacroRepository(IScopeAccessor scopeAccessor, AppCaches cache, ILogger logger, IShortStringHelper shortStringHelper)
|
|
: base(scopeAccessor, cache, logger)
|
|
{
|
|
_shortStringHelper = shortStringHelper;
|
|
}
|
|
|
|
protected override IMacro PerformGet(int id)
|
|
{
|
|
var sql = GetBaseQuery(false);
|
|
sql.Where(GetBaseWhereClause(), new { id });
|
|
return GetBySql(sql);
|
|
}
|
|
|
|
public IMacro Get(Guid id)
|
|
{
|
|
var sql = GetBaseQuery().Where("uniqueId=@Id", new { Id = id });
|
|
return GetBySql(sql);
|
|
}
|
|
|
|
private IMacro GetBySql(Sql sql)
|
|
{
|
|
var macroDto = Database
|
|
.FetchOneToMany<MacroDto>(x => x.MacroPropertyDtos, sql)
|
|
.FirstOrDefault();
|
|
|
|
if (macroDto == null)
|
|
return null;
|
|
|
|
var entity = MacroFactory.BuildEntity(_shortStringHelper, macroDto);
|
|
|
|
// reset dirty initial properties (U4-1946)
|
|
((BeingDirtyBase)entity).ResetDirtyProperties(false);
|
|
|
|
return entity;
|
|
}
|
|
|
|
public IEnumerable<IMacro> GetMany(params Guid[] ids)
|
|
{
|
|
return ids.Length > 0 ? ids.Select(Get) : GetAllNoIds();
|
|
}
|
|
|
|
public bool Exists(Guid id)
|
|
{
|
|
return Get(id) != null;
|
|
}
|
|
|
|
protected override IEnumerable<IMacro> PerformGetAll(params int[] ids)
|
|
{
|
|
return ids.Length > 0 ? ids.Select(Get) : GetAllNoIds();
|
|
}
|
|
|
|
private IEnumerable<IMacro> GetAllNoIds()
|
|
{
|
|
var sql = GetBaseQuery(false)
|
|
//must be sorted this way for the relator to work
|
|
.OrderBy<MacroDto>(x => x.Id);
|
|
|
|
return Database
|
|
.FetchOneToMany<MacroDto>(x => x.MacroPropertyDtos, sql)
|
|
.Transform(ConvertFromDtos)
|
|
.ToArray(); // do it now and once
|
|
}
|
|
|
|
private IEnumerable<IMacro> ConvertFromDtos(IEnumerable<MacroDto> dtos)
|
|
{
|
|
|
|
foreach (var entity in dtos.Select(x => MacroFactory.BuildEntity(_shortStringHelper, x)))
|
|
{
|
|
// reset dirty initial properties (U4-1946)
|
|
((BeingDirtyBase)entity).ResetDirtyProperties(false);
|
|
|
|
yield return entity;
|
|
}
|
|
}
|
|
|
|
protected override IEnumerable<IMacro> PerformGetByQuery(IQuery<IMacro> query)
|
|
{
|
|
var sqlClause = GetBaseQuery(false);
|
|
var translator = new SqlTranslator<IMacro>(sqlClause, query);
|
|
var sql = translator.Translate();
|
|
|
|
return Database
|
|
.FetchOneToMany<MacroDto>(x => x.MacroPropertyDtos, sql)
|
|
.Select(x => Get(x.Id));
|
|
}
|
|
|
|
protected override Sql<ISqlContext> GetBaseQuery(bool isCount)
|
|
{
|
|
return isCount ? Sql().SelectCount().From<MacroDto>() : GetBaseQuery();
|
|
}
|
|
|
|
private Sql<ISqlContext> GetBaseQuery()
|
|
{
|
|
return Sql()
|
|
.SelectAll()
|
|
.From<MacroDto>()
|
|
.LeftJoin<MacroPropertyDto>()
|
|
.On<MacroDto, MacroPropertyDto>(left => left.Id, right => right.Macro);
|
|
}
|
|
|
|
protected override string GetBaseWhereClause()
|
|
{
|
|
return "cmsMacro.id = @id";
|
|
}
|
|
|
|
protected override IEnumerable<string> GetDeleteClauses()
|
|
{
|
|
var list = new List<string>
|
|
{
|
|
"DELETE FROM cmsMacroProperty WHERE macro = @id",
|
|
"DELETE FROM cmsMacro WHERE id = @id"
|
|
};
|
|
return list;
|
|
}
|
|
|
|
protected override Guid NodeObjectTypeId => throw new NotImplementedException();
|
|
|
|
protected override void PersistNewItem(IMacro entity)
|
|
{
|
|
entity.AddingEntity();
|
|
|
|
var dto = MacroFactory.BuildDto(entity);
|
|
|
|
var id = Convert.ToInt32(Database.Insert(dto));
|
|
entity.Id = id;
|
|
|
|
foreach (var propDto in dto.MacroPropertyDtos)
|
|
{
|
|
//need to set the id explicitly here
|
|
propDto.Macro = id;
|
|
var propId = Convert.ToInt32(Database.Insert(propDto));
|
|
entity.Properties[propDto.Alias].Id = propId;
|
|
}
|
|
|
|
entity.ResetDirtyProperties();
|
|
}
|
|
|
|
protected override void PersistUpdatedItem(IMacro entity)
|
|
{
|
|
entity.UpdatingEntity();
|
|
var dto = MacroFactory.BuildDto(entity);
|
|
|
|
Database.Update(dto);
|
|
|
|
//update the properties if they've changed
|
|
var macro = (Macro)entity;
|
|
if (macro.IsPropertyDirty("Properties") || macro.Properties.Values.Any(x => x.IsDirty()))
|
|
{
|
|
var ids = dto.MacroPropertyDtos.Where(x => x.Id > 0).Select(x => x.Id).ToArray();
|
|
if (ids.Length > 0)
|
|
Database.Delete<MacroPropertyDto>("WHERE macro=@macro AND id NOT IN (@ids)", new { macro = dto.Id, ids });
|
|
else
|
|
Database.Delete<MacroPropertyDto>("WHERE macro=@macro", new { macro = dto.Id });
|
|
|
|
// detect new aliases, replace with temp aliases
|
|
// this ensures that we don't have collisions, ever
|
|
var aliases = new Dictionary<string, string>();
|
|
foreach (var propDto in dto.MacroPropertyDtos)
|
|
{
|
|
var prop = macro.Properties.Values.FirstOrDefault(x => x.Id == propDto.Id);
|
|
if (prop == null) throw new Exception("oops: property.");
|
|
if (propDto.Id == 0 || prop.IsPropertyDirty("Alias"))
|
|
{
|
|
var tempAlias = Guid.NewGuid().ToString("N").Substring(0, 8);
|
|
aliases[tempAlias] = propDto.Alias;
|
|
propDto.Alias = tempAlias;
|
|
}
|
|
}
|
|
|
|
// insert or update existing properties, with temp aliases
|
|
foreach (var propDto in dto.MacroPropertyDtos)
|
|
{
|
|
if (propDto.Id == 0)
|
|
{
|
|
// insert
|
|
propDto.Id = Convert.ToInt32(Database.Insert(propDto));
|
|
macro.Properties[aliases[propDto.Alias]].Id = propDto.Id;
|
|
}
|
|
else
|
|
{
|
|
// update
|
|
var property = macro.Properties.Values.FirstOrDefault(x => x.Id == propDto.Id);
|
|
if (property == null) throw new Exception("oops: property.");
|
|
if (property.IsDirty())
|
|
Database.Update(propDto);
|
|
}
|
|
}
|
|
|
|
// replace the temp aliases with the real ones
|
|
foreach (var propDto in dto.MacroPropertyDtos)
|
|
{
|
|
if (aliases.ContainsKey(propDto.Alias) == false) continue;
|
|
|
|
propDto.Alias = aliases[propDto.Alias];
|
|
Database.Update(propDto);
|
|
}
|
|
}
|
|
|
|
entity.ResetDirtyProperties();
|
|
}
|
|
}
|
|
}
|