Merge branch 'v15/dev' into v16/merge-from-15
# Conflicts: # src/Umbraco.Cms.Api.Management/Controllers/PublishedCache/RebuildPublishedCacheController.cs # src/Umbraco.Cms.Api.Management/Factories/UserPresentationFactory.cs # src/Umbraco.Core/Persistence/Repositories/ITrackedReferencesRepository.cs # src/Umbraco.Core/Services/ContentEditingService.cs # src/Umbraco.Core/Services/DataTypeService.cs # src/Umbraco.Core/Services/IContentEditingService.cs # src/Umbraco.Core/Services/IDataTypeService.cs # src/Umbraco.Core/Services/ITrackedReferencesService.cs # src/Umbraco.Core/Services/RelationService.cs # src/Umbraco.Core/Services/TrackedReferencesService.cs # src/Umbraco.Infrastructure/Examine/Deferred/DeliveryApiContentIndexHandleContentTypeChanges.cs # src/Umbraco.Infrastructure/Examine/DeliveryApiIndexingHandler.cs # src/Umbraco.Infrastructure/Persistence/Repositories/Implement/TrackedReferencesRepository.cs # src/Umbraco.Web.UI.Client/src/external/backend-api/src/sdk.gen.ts # src/Umbraco.Web.UI.Client/src/mocks/data/document-blueprint/document-blueprint.data.ts # src/Umbraco.Web.UI.Client/src/mocks/data/document/document.db.ts # src/Umbraco.Web.UI.Client/src/packages/core/router/modal-registration/modal-route-registration.controller.ts # src/Umbraco.Web.UI.Client/src/packages/core/router/route/route.context.ts # src/Umbraco.Web.UI.Client/src/packages/core/router/route/route.interface.ts # src/Umbraco.Web.UI.Client/src/packages/core/router/route/router-slot.element.ts # src/Umbraco.Web.UI.Client/src/packages/core/router/router-slot/model.ts # src/Umbraco.Web.UI.Client/src/packages/data-type/reference/repository/data-type-reference.server.data.ts # src/Umbraco.Web.UI.Client/src/packages/documents/documents/publishing/repository/document-publishing.server.data-source.ts # src/Umbraco.Web.UI.Client/src/packages/documents/documents/rollback/entity-action/rollback.action.ts # tests/Umbraco.Tests.AcceptanceTest/package-lock.json # tests/Umbraco.Tests.AcceptanceTest/package.json # tests/Umbraco.Tests.Common/Builders/UserGroupBuilder.cs # tests/Umbraco.Tests.Integration/Umbraco.Core/Services/TemporaryFileServiceTests.cs
This commit is contained in:
@@ -2,6 +2,7 @@ using Examine;
|
||||
using Examine.Search;
|
||||
using Umbraco.Cms.Core.DeliveryApi;
|
||||
using Umbraco.Cms.Core.HostedServices;
|
||||
using Umbraco.Cms.Core.HostedServices;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Services.Changes;
|
||||
|
||||
@@ -20,6 +20,72 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
_umbracoMapper = umbracoMapper;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a page of items used in any kind of relation from selected integer ids.
|
||||
/// </summary>
|
||||
public IEnumerable<RelationItem> GetPagedItemsWithRelations(int[] ids, long pageIndex, int pageSize,
|
||||
bool filterMustBeIsDependency, out long totalRecords)
|
||||
{
|
||||
Sql<ISqlContext> innerUnionSql = GetInnerUnionSql();
|
||||
|
||||
Sql<ISqlContext>? sql = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql()
|
||||
.SelectDistinct(
|
||||
"[x].[id] as nodeId",
|
||||
"[n].[uniqueId] as nodeKey",
|
||||
"[n].[text] as nodeName",
|
||||
"[n].[nodeObjectType] as nodeObjectType",
|
||||
"[d].[published] as nodePublished",
|
||||
"[ctn].[uniqueId] as contentTypeKey",
|
||||
"[ct].[icon] as contentTypeIcon",
|
||||
"[ct].[alias] as contentTypeAlias",
|
||||
"[ctn].[text] as contentTypeName",
|
||||
"[x].[alias] as relationTypeAlias",
|
||||
"[x].[name] as relationTypeName",
|
||||
"[x].[isDependency] as relationTypeIsDependency",
|
||||
"[x].[dual] as relationTypeIsBidirectional")
|
||||
.From<NodeDto>("n")
|
||||
.InnerJoinNested(innerUnionSql, "x")
|
||||
.On<NodeDto, UnionHelperDto>((n, x) => n.NodeId == x.Id, "n", "x")
|
||||
.LeftJoin<ContentDto>("c")
|
||||
.On<NodeDto, ContentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "c")
|
||||
.LeftJoin<ContentTypeDto>("ct")
|
||||
.On<ContentDto, ContentTypeDto>(
|
||||
(left, right) => left.ContentTypeId == right.NodeId,
|
||||
aliasLeft: "c",
|
||||
aliasRight: "ct")
|
||||
.LeftJoin<NodeDto>("ctn")
|
||||
.On<ContentTypeDto, NodeDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "ct",
|
||||
aliasRight: "ctn")
|
||||
.LeftJoin<DocumentDto>("d")
|
||||
.On<NodeDto, DocumentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "d");
|
||||
|
||||
if (ids.Any())
|
||||
{
|
||||
sql = sql?.Where<NodeDto>(x => ids.Contains(x.NodeId), "n");
|
||||
}
|
||||
|
||||
if (filterMustBeIsDependency)
|
||||
{
|
||||
sql = sql?.Where<RelationTypeDto>(rt => rt.IsDependency, "x");
|
||||
}
|
||||
|
||||
// Ordering is required for paging
|
||||
sql = sql?.OrderBy<RelationTypeDto>(x => x.Alias, "x");
|
||||
|
||||
Page<RelationItemDto>? pagedResult = _scopeAccessor.AmbientScope?.Database.Page<RelationItemDto>(pageIndex + 1, pageSize, sql);
|
||||
totalRecords = Convert.ToInt32(pagedResult?.TotalItems);
|
||||
|
||||
return pagedResult?.Items.Select(MapDtoToEntity) ?? Enumerable.Empty<RelationItem>();
|
||||
}
|
||||
|
||||
private Sql<ISqlContext> GetInnerUnionSql()
|
||||
{
|
||||
if (_scopeAccessor.AmbientScope is null)
|
||||
@@ -91,6 +157,148 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
return innerUnionSql;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a page of the descending items that have any references, given a parent id.
|
||||
/// </summary>
|
||||
public IEnumerable<RelationItem> GetPagedDescendantsInReferences(
|
||||
int parentId,
|
||||
long pageIndex,
|
||||
int pageSize,
|
||||
bool filterMustBeIsDependency,
|
||||
out long totalRecords)
|
||||
{
|
||||
SqlSyntax.ISqlSyntaxProvider? syntax = _scopeAccessor.AmbientScope?.Database.SqlContext.SqlSyntax;
|
||||
|
||||
// Gets the path of the parent with ",%" added
|
||||
Sql<ISqlContext>? subsubQuery = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql()
|
||||
.Select(syntax?.GetConcat("[node].[path]", "',%'"))
|
||||
.From<NodeDto>("node")
|
||||
.Where<NodeDto>(x => x.NodeId == parentId, "node");
|
||||
|
||||
// Gets the descendants of the parent node
|
||||
Sql<ISqlContext>? subQuery = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql()
|
||||
.Select<NodeDto>(x => x.NodeId)
|
||||
.From<NodeDto>()
|
||||
.WhereLike<NodeDto>(x => x.Path, subsubQuery);
|
||||
|
||||
Sql<ISqlContext> innerUnionSql = GetInnerUnionSql();
|
||||
|
||||
Sql<ISqlContext>? sql = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql().SelectDistinct(
|
||||
"[x].[id] as nodeId",
|
||||
"[n].[uniqueId] as nodeKey",
|
||||
"[n].[text] as nodeName",
|
||||
"[n].[nodeObjectType] as nodeObjectType",
|
||||
"[d].[published] as nodePublished",
|
||||
"[ctn].[uniqueId] as contentTypeKey",
|
||||
"[ct].[icon] as contentTypeIcon",
|
||||
"[ct].[alias] as contentTypeAlias",
|
||||
"[ctn].[text] as contentTypeName",
|
||||
"[x].[alias] as relationTypeAlias",
|
||||
"[x].[name] as relationTypeName",
|
||||
"[x].[isDependency] as relationTypeIsDependency",
|
||||
"[x].[dual] as relationTypeIsBidirectional")
|
||||
.From<NodeDto>("n")
|
||||
.InnerJoinNested(innerUnionSql, "x")
|
||||
.On<NodeDto, UnionHelperDto>((n, x) => n.NodeId == x.Id, "n", "x")
|
||||
.LeftJoin<ContentDto>("c")
|
||||
.On<NodeDto, ContentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "c")
|
||||
.LeftJoin<ContentTypeDto>("ct")
|
||||
.On<ContentDto, ContentTypeDto>(
|
||||
(left, right) => left.ContentTypeId == right.NodeId,
|
||||
aliasLeft: "c",
|
||||
aliasRight: "ct")
|
||||
.LeftJoin<NodeDto>("ctn")
|
||||
.On<ContentTypeDto, NodeDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "ct",
|
||||
aliasRight: "ctn")
|
||||
.LeftJoin<DocumentDto>("d")
|
||||
.On<NodeDto, DocumentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "d");
|
||||
|
||||
sql = sql?.WhereIn((System.Linq.Expressions.Expression<Func<NodeDto, object?>>)(x => x.NodeId), subQuery, "n");
|
||||
|
||||
if (filterMustBeIsDependency)
|
||||
{
|
||||
sql = sql?.Where<RelationTypeDto>(rt => rt.IsDependency, "x");
|
||||
}
|
||||
|
||||
// Ordering is required for paging
|
||||
sql = sql?.OrderBy<RelationTypeDto>(x => x.Alias, "x");
|
||||
|
||||
Page<RelationItemDto>? pagedResult = _scopeAccessor.AmbientScope?.Database.Page<RelationItemDto>(pageIndex + 1, pageSize, sql);
|
||||
totalRecords = Convert.ToInt32(pagedResult?.TotalItems);
|
||||
|
||||
return pagedResult?.Items.Select(MapDtoToEntity) ?? Enumerable.Empty<RelationItem>();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a page of items which are in relation with the current item.
|
||||
/// Basically, shows the items which depend on the current item.
|
||||
/// </summary>
|
||||
public IEnumerable<RelationItem> GetPagedRelationsForItem(int id, long pageIndex, int pageSize,
|
||||
bool filterMustBeIsDependency, out long totalRecords)
|
||||
{
|
||||
Sql<ISqlContext> innerUnionSql = GetInnerUnionSql();
|
||||
Sql<ISqlContext>? sql = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql().SelectDistinct(
|
||||
"[x].[otherId] as nodeId",
|
||||
"[n].[uniqueId] as nodeKey",
|
||||
"[n].[text] as nodeName",
|
||||
"[n].[nodeObjectType] as nodeObjectType",
|
||||
"[d].[published] as nodePublished",
|
||||
"[ctn].[uniqueId] as contentTypeKey",
|
||||
"[ct].[icon] as contentTypeIcon",
|
||||
"[ct].[alias] as contentTypeAlias",
|
||||
"[ctn].[text] as contentTypeName",
|
||||
"[x].[alias] as relationTypeAlias",
|
||||
"[x].[name] as relationTypeName",
|
||||
"[x].[isDependency] as relationTypeIsDependency",
|
||||
"[x].[dual] as relationTypeIsBidirectional")
|
||||
.From<NodeDto>("n")
|
||||
.InnerJoinNested(innerUnionSql, "x")
|
||||
.On<NodeDto, UnionHelperDto>((n, x) => n.NodeId == x.OtherId, "n", "x")
|
||||
.LeftJoin<ContentDto>("c")
|
||||
.On<NodeDto, ContentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "c")
|
||||
.LeftJoin<ContentTypeDto>("ct")
|
||||
.On<ContentDto, ContentTypeDto>(
|
||||
(left, right) => left.ContentTypeId == right.NodeId,
|
||||
aliasLeft: "c",
|
||||
aliasRight: "ct")
|
||||
.LeftJoin<NodeDto>("ctn")
|
||||
.On<ContentTypeDto, NodeDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "ct",
|
||||
aliasRight: "ctn")
|
||||
.LeftJoin<DocumentDto>("d")
|
||||
.On<NodeDto, DocumentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "d")
|
||||
.Where<UnionHelperDto>(x => x.Id == id, "x");
|
||||
|
||||
if (filterMustBeIsDependency)
|
||||
{
|
||||
sql = sql?.Where<RelationTypeDto>(rt => rt.IsDependency, "x");
|
||||
}
|
||||
|
||||
// Ordering is required for paging
|
||||
sql = sql?.OrderBy<RelationTypeDto>(x => x.Alias, "x");
|
||||
|
||||
Page<RelationItemDto>? pagedResult = _scopeAccessor.AmbientScope?.Database.Page<RelationItemDto>(pageIndex + 1, pageSize, sql);
|
||||
totalRecords = Convert.ToInt32(pagedResult?.TotalItems);
|
||||
|
||||
return pagedResult?.Items.Select(MapDtoToEntity) ?? Enumerable.Empty<RelationItem>();
|
||||
}
|
||||
|
||||
public IEnumerable<RelationItemModel> GetPagedRelationsForItem(
|
||||
Guid key,
|
||||
long skip,
|
||||
@@ -388,6 +596,91 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
|
||||
return _umbracoMapper.MapEnumerable<RelationItemDto, RelationItemModel>(pagedResult);
|
||||
}
|
||||
|
||||
public IEnumerable<RelationItemModel> GetPagedDescendantsInReferences(
|
||||
int parentId,
|
||||
long skip,
|
||||
long take,
|
||||
bool filterMustBeIsDependency,
|
||||
out long totalRecords)
|
||||
{
|
||||
SqlSyntax.ISqlSyntaxProvider? syntax = _scopeAccessor.AmbientScope?.Database.SqlContext.SqlSyntax;
|
||||
|
||||
// Gets the path of the parent with ",%" added
|
||||
Sql<ISqlContext>? subsubQuery = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql()
|
||||
.Select(syntax?.GetConcat("[node].[path]", "',%'"))
|
||||
.From<NodeDto>("node")
|
||||
.Where<NodeDto>(x => x.NodeId == parentId, "node");
|
||||
|
||||
// Gets the descendants of the parent node
|
||||
Sql<ISqlContext>? subQuery = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql()
|
||||
.Select<NodeDto>(x => x.NodeId)
|
||||
.From<NodeDto>()
|
||||
.WhereLike<NodeDto>(x => x.Path, subsubQuery);
|
||||
|
||||
Sql<ISqlContext> innerUnionSql = GetInnerUnionSql();
|
||||
Sql<ISqlContext>? sql = _scopeAccessor.AmbientScope?.Database.SqlContext.Sql().SelectDistinct(
|
||||
"[x].[id] as nodeId",
|
||||
"[n].[uniqueId] as nodeKey",
|
||||
"[n].[text] as nodeName",
|
||||
"[n].[nodeObjectType] as nodeObjectType",
|
||||
"[ctn].[uniqueId] as contentTypeKey",
|
||||
"[ct].[icon] as contentTypeIcon",
|
||||
"[ct].[alias] as contentTypeAlias",
|
||||
"[ctn].[text] as contentTypeName",
|
||||
"[x].[alias] as relationTypeAlias",
|
||||
"[x].[name] as relationTypeName",
|
||||
"[x].[isDependency] as relationTypeIsDependency",
|
||||
"[x].[dual] as relationTypeIsBidirectional")
|
||||
.From<NodeDto>("n")
|
||||
.InnerJoinNested(innerUnionSql, "x")
|
||||
.On<NodeDto, UnionHelperDto>((n, x) => n.NodeId == x.Id, "n", "x")
|
||||
.LeftJoin<ContentDto>("c").On<NodeDto, ContentDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "n",
|
||||
aliasRight: "c")
|
||||
.LeftJoin<ContentTypeDto>("ct")
|
||||
.On<ContentDto, ContentTypeDto>(
|
||||
(left, right) => left.ContentTypeId == right.NodeId,
|
||||
aliasLeft: "c",
|
||||
aliasRight: "ct")
|
||||
.LeftJoin<NodeDto>("ctn")
|
||||
.On<ContentTypeDto, NodeDto>(
|
||||
(left, right) => left.NodeId == right.NodeId,
|
||||
aliasLeft: "ct",
|
||||
aliasRight: "ctn");
|
||||
sql = sql?.WhereIn(
|
||||
(System.Linq.Expressions.Expression<Func<NodeDto, object?>>)(x => x.NodeId),
|
||||
subQuery,
|
||||
"n");
|
||||
|
||||
if (filterMustBeIsDependency)
|
||||
{
|
||||
sql = sql?.Where<RelationTypeDto>(rt => rt.IsDependency, "x");
|
||||
}
|
||||
|
||||
// find the count before ordering
|
||||
totalRecords = _scopeAccessor.AmbientScope?.Database.Count(sql!) ?? 0;
|
||||
|
||||
RelationItemDto[] pagedResult;
|
||||
|
||||
//Only to all this, if there is items
|
||||
if (totalRecords > 0)
|
||||
{
|
||||
// Ordering is required for paging
|
||||
sql = sql?.OrderBy<RelationTypeDto>(x => x.Alias, "x");
|
||||
|
||||
pagedResult =
|
||||
_scopeAccessor.AmbientScope?.Database.SkipTake<RelationItemDto>(skip, take, sql).ToArray() ??
|
||||
Array.Empty<RelationItemDto>();
|
||||
}
|
||||
else
|
||||
{
|
||||
pagedResult = Array.Empty<RelationItemDto>();
|
||||
}
|
||||
|
||||
return _umbracoMapper.MapEnumerable<RelationItemDto, RelationItemModel>(pagedResult);
|
||||
}
|
||||
|
||||
private class UnionHelperDto
|
||||
{
|
||||
[Column("id")] public int Id { get; set; }
|
||||
|
||||
Reference in New Issue
Block a user