U4-10023 - fix media picker for multiple start nodes

This commit is contained in:
Stephan
2017-07-14 20:13:57 +02:00
parent 3f6ec6e36f
commit 29aaa26022
7 changed files with 185 additions and 5 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
namespace Umbraco.Core.Persistence.Querying
@@ -16,6 +17,11 @@ namespace Umbraco.Core.Persistence.Querying
/// <returns>This instance so calls to this method are chainable</returns>
IQuery<T> Where(Expression<Func<T, bool>> predicate);
/// <summary>
/// Adds a set of OR-ed where clauses to the query.
/// </summary>
/// <param name="predicates"></param>
/// <returns>This instance so calls to this method are chainable.</returns>
IQuery<T> WhereAny(IEnumerable<Expression<Func<T, bool>>> predicates);
}
}

View File

@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
namespace Umbraco.Core.Persistence.Querying
{
@@ -39,6 +40,50 @@ namespace Umbraco.Core.Persistence.Querying
return this;
}
/// <summary>
/// Adds a set of OR-ed where clauses to the query.
/// </summary>
/// <param name="predicates"></param>
/// <returns>This instance so calls to this method are chainable.</returns>
public virtual IQuery<T> WhereAny(IEnumerable<Expression<Func<T, bool>>> predicates)
{
if (predicates == null) return this;
StringBuilder sb = null;
List<object> parameters = null;
Sql sql = null;
foreach (var predicate in predicates)
{
// see notes in Where()
var expressionHelper = new ModelToSqlExpressionVisitor<T>();
var whereExpression = expressionHelper.Visit(predicate);
if (sb == null)
{
sb = new StringBuilder("(");
parameters = new List<object>();
sql = new Sql();
}
else
{
sb.Append(" OR ");
sql.Append(" OR ");
}
sb.Append(whereExpression);
parameters.AddRange(expressionHelper.GetSqlParameters());
sql.Append(whereExpression, expressionHelper.GetSqlParameters());
}
if (sb == null) return this;
sb.Append(")");
//_wheres.Add(Tuple.Create(sb.ToString(), parameters.ToArray()));
_wheres.Add(Tuple.Create("(" + sql.SQL + ")", sql.Arguments));
return this;
}
/// <summary>
/// Returns all translated where clauses and their sql parameters
/// </summary>

View File

@@ -1,5 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using Umbraco.Core.Cache;
using Umbraco.Core.CodeAnnotations;
using Umbraco.Core.Events;
@@ -361,6 +364,40 @@ namespace Umbraco.Core.Services
return contents;
}
}
/// <summary>
/// Returns a paged collection of descendants.
/// </summary>
public IEnumerable<IUmbracoEntity> GetPagedDescendants(IEnumerable<int> ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "")
{
var objectTypeId = umbracoObjectType.GetGuid();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateEntityRepository(uow);
var query = Query<IUmbracoEntity>.Builder;
var idsA = ids.ToArray();
if (idsA.All(x => x != Constants.System.Root))
{
var clauses = new List<Expression<Func<IUmbracoEntity, bool>>>();
foreach (var id in idsA)
{
var qid = id;
clauses.Add(x => x.Path.SqlContains(string.Format(",{0},", qid), TextColumnType.NVarchar) || x.Path.SqlEndsWith(string.Format(",{0}", qid), TextColumnType.NVarchar));
}
query.WhereAny(clauses);
}
IQuery<IUmbracoEntity> filterQuery = null;
if (filter.IsNullOrWhiteSpace() == false)
{
filterQuery = Query<IUmbracoEntity>.Builder.Where(x => x.Name.Contains(filter));
}
var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
return contents;
}
}
/// <summary>
/// Returns a paged collection of descendants from the root

View File

@@ -175,6 +175,12 @@ namespace Umbraco.Core.Services
IEnumerable<IUmbracoEntity> GetPagedDescendants(int id, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Returns a paged collection of descendants
/// </summary>
IEnumerable<IUmbracoEntity> GetPagedDescendants(IEnumerable<int> ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
/// <summary>
/// Returns a paged collection of descendants from the root
/// </summary>

View File

@@ -118,6 +118,7 @@
</Reference>
<Reference Include="System.DirectoryServices.AccountManagement" />
<Reference Include="System.Drawing" />
<Reference Include="System.Linq.Expressions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Caching" />

View File

@@ -19,6 +19,7 @@ using Umbraco.Web.Dynamics;
using System.Text.RegularExpressions;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using System.Web.Http.Controllers;
using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Xml;
namespace Umbraco.Web.Editors
@@ -541,11 +542,30 @@ namespace Umbraco.Web.Editors
var objectType = ConvertToObjectType(type);
if (objectType.HasValue)
{
IEnumerable<IUmbracoEntity> entities;
long totalRecords;
//if it's from root, don't return recycled
var entities = id == Constants.System.Root
? Services.EntityService.GetPagedDescendantsFromRoot(objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter, includeTrashed:false)
: Services.EntityService.GetPagedDescendants(id, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter);
if (id == Constants.System.Root)
{
int[] aids = null;
switch (type)
{
case UmbracoEntityTypes.Document:
aids = Security.CurrentUser.AllStartContentIds;
break;
case UmbracoEntityTypes.Media:
aids = Security.CurrentUser.AllStartMediaIds;
break;
}
entities = aids != null && aids.Length > 0
? Services.EntityService.GetPagedDescendants(aids, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter)
: Services.EntityService.GetPagedDescendantsFromRoot(objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter, includeTrashed: false);
}
else
{
entities = Services.EntityService.GetPagedDescendants(id, objectType.Value, pageNumber - 1, pageSize, out totalRecords, orderBy, orderDirection, filter);
}
if (totalRecords == 0)
{
@@ -618,9 +638,17 @@ namespace Umbraco.Web.Editors
{
if (startNode > 0)
{
// descendants
// "__Path: -1*,1234,*" -- the first "*" stands for path-to-1234
sb.Append("__Path: \\-1*\\,");
sb.Append(startNode.ToString(CultureInfo.InvariantCulture));
sb.Append("\\,* ");
// self
// "__Path: -1*,1234" -- the first "*" stands for path-to-1234
sb.Append("__Path: \\-1*\\,");
sb.Append(startNode.ToString(CultureInfo.InvariantCulture));
sb.Append(" ");
}
}
if (startNodes.Length > 0)
@@ -918,6 +946,37 @@ namespace Umbraco.Web.Editors
var ids = Services.EntityService.Get(id).Path.Split(',').Select(int.Parse).Distinct().ToArray();
int[] aids = null;
switch (entityType)
{
case UmbracoEntityTypes.Document:
aids = Security.CurrentUser.AllStartContentIds;
break;
case UmbracoEntityTypes.Media:
aids = Security.CurrentUser.AllStartMediaIds;
break;
}
if (aids != null && aids.Length > 0)
{
var lids = new List<int>();
var ok = false;
foreach (var i in ids)
{
if (ok)
{
lids.Add(i);
continue;
}
if (aids.Contains(i))
{
lids.Add(i);
ok = true;
}
}
ids = lids.ToArray();
}
return ids.Length == 0
? Enumerable.Empty<EntityBasic>()
: Services.EntityService.GetAll(objectType.Value, ids)

View File

@@ -250,6 +250,13 @@ namespace Umbraco.Web.Editors
}
#region GetChildren
private int[] _userStartNodes;
protected int[] UserStartNodes
{
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartMediaIds); }
}
/// <summary>
/// Returns the child media objects - using the entity INT id
/// </summary>
@@ -262,6 +269,25 @@ namespace Umbraco.Web.Editors
bool orderBySystemField = true,
string filter = "")
{
//if a request is made for the root node data but the user's start node is not the default, then
// we need to return their start nodes
if (id == Constants.System.Root && UserStartNodes.Length > 0 && UserStartNodes.Contains(Constants.System.Root) == false)
{
if (pageNumber > 0)
return new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(0, 0, 0);
var nodes = Services.MediaService.GetByIds(UserStartNodes).ToArray();
if (nodes.Length == 0)
return new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(0, 0, 0);
if (pageSize < nodes.Length) pageSize = nodes.Length; // bah
var pr = new PagedResult<ContentItemBasic<ContentPropertyBasic, IMedia>>(nodes.Length, pageNumber, pageSize)
{
Items = nodes.Select(Mapper.Map<IMedia, ContentItemBasic<ContentPropertyBasic, IMedia>>)
};
return pr;
}
// else proceed as usual
long totalChildren;
IMedia[] children;
if (pageNumber > 0 && pageSize > 0)