diff --git a/src/Umbraco.Core/Persistence/Querying/IQuery.cs b/src/Umbraco.Core/Persistence/Querying/IQuery.cs
index ae986baddc..cd08274c1b 100644
--- a/src/Umbraco.Core/Persistence/Querying/IQuery.cs
+++ b/src/Umbraco.Core/Persistence/Querying/IQuery.cs
@@ -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
/// This instance so calls to this method are chainable
IQuery Where(Expression> predicate);
-
+ ///
+ /// Adds a set of OR-ed where clauses to the query.
+ ///
+ ///
+ /// This instance so calls to this method are chainable.
+ IQuery WhereAny(IEnumerable>> predicates);
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Querying/Query.cs b/src/Umbraco.Core/Persistence/Querying/Query.cs
index 6213ca5ed6..d49296c6d0 100644
--- a/src/Umbraco.Core/Persistence/Querying/Query.cs
+++ b/src/Umbraco.Core/Persistence/Querying/Query.cs
@@ -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;
}
+ ///
+ /// Adds a set of OR-ed where clauses to the query.
+ ///
+ ///
+ /// This instance so calls to this method are chainable.
+ public virtual IQuery WhereAny(IEnumerable>> predicates)
+ {
+ if (predicates == null) return this;
+
+ StringBuilder sb = null;
+ List parameters = null;
+ Sql sql = null;
+ foreach (var predicate in predicates)
+ {
+ // see notes in Where()
+ var expressionHelper = new ModelToSqlExpressionVisitor();
+ var whereExpression = expressionHelper.Visit(predicate);
+
+ if (sb == null)
+ {
+ sb = new StringBuilder("(");
+ parameters = new List();
+ 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;
+ }
+
///
/// Returns all translated where clauses and their sql parameters
///
diff --git a/src/Umbraco.Core/Services/EntityService.cs b/src/Umbraco.Core/Services/EntityService.cs
index 04d6c276b2..ecf1b5a216 100644
--- a/src/Umbraco.Core/Services/EntityService.cs
+++ b/src/Umbraco.Core/Services/EntityService.cs
@@ -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;
}
}
+ ///
+ /// Returns a paged collection of descendants.
+ ///
+ public IEnumerable GetPagedDescendants(IEnumerable 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.Builder;
+ var idsA = ids.ToArray();
+ if (idsA.All(x => x != Constants.System.Root))
+ {
+ var clauses = new List>>();
+ 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 filterQuery = null;
+ if (filter.IsNullOrWhiteSpace() == false)
+ {
+ filterQuery = Query.Builder.Where(x => x.Name.Contains(filter));
+ }
+
+ var contents = repository.GetPagedResultsByQuery(query, objectTypeId, pageIndex, pageSize, out totalRecords, orderBy, orderDirection, filterQuery);
+ return contents;
+ }
+ }
///
/// Returns a paged collection of descendants from the root
diff --git a/src/Umbraco.Core/Services/IEntityService.cs b/src/Umbraco.Core/Services/IEntityService.cs
index 82e5227cf2..f6c75c2e98 100644
--- a/src/Umbraco.Core/Services/IEntityService.cs
+++ b/src/Umbraco.Core/Services/IEntityService.cs
@@ -175,6 +175,12 @@ namespace Umbraco.Core.Services
IEnumerable GetPagedDescendants(int id, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
+ ///
+ /// Returns a paged collection of descendants
+ ///
+ IEnumerable GetPagedDescendants(IEnumerable ids, UmbracoObjectTypes umbracoObjectType, long pageIndex, int pageSize, out long totalRecords,
+ string orderBy = "path", Direction orderDirection = Direction.Ascending, string filter = "");
+
///
/// Returns a paged collection of descendants from the root
///
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 8a635b966c..109b11f156 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -118,6 +118,7 @@
+
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index 37d712c362..a2aa8e6b4d 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -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 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();
+ 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()
: Services.EntityService.GetAll(objectType.Value, ids)
diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs
index ed4b1c2f63..1603615a58 100644
--- a/src/Umbraco.Web/Editors/MediaController.cs
+++ b/src/Umbraco.Web/Editors/MediaController.cs
@@ -250,6 +250,13 @@ namespace Umbraco.Web.Editors
}
#region GetChildren
+
+ private int[] _userStartNodes;
+ protected int[] UserStartNodes
+ {
+ get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartMediaIds); }
+ }
+
///
/// Returns the child media objects - using the entity INT id
///
@@ -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>(0, 0, 0);
+ var nodes = Services.MediaService.GetByIds(UserStartNodes).ToArray();
+ if (nodes.Length == 0)
+ return new PagedResult>(0, 0, 0);
+ if (pageSize < nodes.Length) pageSize = nodes.Length; // bah
+ var pr = new PagedResult>(nodes.Length, pageNumber, pageSize)
+ {
+ Items = nodes.Select(Mapper.Map>)
+ };
+ return pr;
+ }
+
+ // else proceed as usual
+
long totalChildren;
IMedia[] children;
if (pageNumber > 0 && pageSize > 0)