.Builder.Where(x => types.Contains(x.ContentType.Alias));
+ var result = repository.GetByQuery(query);
+
+ // Assert
+ Assert.That(result.Count(), Is.GreaterThanOrEqualTo(11));
+ }
+ }
+
[Test]
public void Can_Perform_GetPagedResultsByQuery_ForFirstPage_On_MediaRepository()
{
@@ -470,7 +526,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.That(result.First().Name, Is.EqualTo("Test File"));
}
}
-
+
[Test]
public void Can_Perform_GetPagedResultsByQuery_WithFilterMatchingAll_On_MediaRepository()
{
diff --git a/src/Umbraco.Tests/Services/MediaServiceTests.cs b/src/Umbraco.Tests/Services/MediaServiceTests.cs
index 8193df911c..82738a26f4 100644
--- a/src/Umbraco.Tests/Services/MediaServiceTests.cs
+++ b/src/Umbraco.Tests/Services/MediaServiceTests.cs
@@ -7,6 +7,7 @@ using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Rdbms;
using Umbraco.Core.Persistence;
+using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Persistence.Repositories;
using Umbraco.Core.Persistence.UnitOfWork;
using Umbraco.Tests.TestHelpers;
@@ -30,6 +31,33 @@ namespace Umbraco.Tests.Services
base.TearDown();
}
+ [Test]
+ public void Get_Paged_Children_With_Media_Type_Filter()
+ {
+ var mediaService = ServiceContext.MediaService;
+ var mediaType1 = MockedContentTypes.CreateImageMediaType("Image2");
+ ServiceContext.ContentTypeService.Save(mediaType1);
+ var mediaType2 = MockedContentTypes.CreateImageMediaType("Image3");
+ ServiceContext.ContentTypeService.Save(mediaType2);
+
+ for (int i = 0; i < 10; i++)
+ {
+ var m1 = MockedMedia.CreateMediaImage(mediaType1, -1);
+ mediaService.Save(m1);
+ var m2 = MockedMedia.CreateMediaImage(mediaType2, -1);
+ mediaService.Save(m2);
+ }
+
+ long total;
+ var result = ServiceContext.MediaService.GetPagedChildren(-1, 0, 11, out total, "SortOrder", Direction.Ascending, true, null, new[] {mediaType1.Id, mediaType2.Id});
+ Assert.AreEqual(11, result.Count());
+ Assert.AreEqual(20, total);
+
+ result = ServiceContext.MediaService.GetPagedChildren(-1, 1, 11, out total, "SortOrder", Direction.Ascending, true, null, new[] { mediaType1.Id, mediaType2.Id });
+ Assert.AreEqual(9, result.Count());
+ Assert.AreEqual(20, total);
+ }
+
[Test]
public void Can_Move_Media()
{
diff --git a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js
index 4b56e55801..c41b7e91c7 100644
--- a/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js
+++ b/src/Umbraco.Web.UI.Client/src/common/resources/media.resource.js
@@ -427,7 +427,9 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
* Retrieves all media children with types used as folders.
* Uses the convention of looking for media items with mediaTypes ending in
* *Folder so will match "Folder", "bannerFolder", "secureFolder" etc,
- *
+ *
+ * NOTE: This will return a max of 500 folders, if more is required it needs to be paged
+ *
* ##usage
*
* mediaResource.getChildFolders(1234)
@@ -445,14 +447,15 @@ function mediaResource($q, $http, umbDataFormatter, umbRequestHelper) {
parentId = -1;
}
+ //NOTE: This will return a max of 500 folders, if more is required it needs to be paged
return umbRequestHelper.resourcePromise(
$http.get(
umbRequestHelper.getApiUrl(
"mediaApiBaseUrl",
"GetChildFolders",
- [
- { id: parentId }
- ])),
+ {
+ id: parentId
+ })),
'Failed to retrieve child folders for media item ' + parentId);
},
diff --git a/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js
index 20e5e3799b..b06a5ca8e3 100644
--- a/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js
+++ b/src/Umbraco.Web.UI.Client/src/common/services/mediatypehelper.service.js
@@ -7,6 +7,19 @@ function mediaTypeHelper(mediaTypeResource, $q) {
var mediaTypeHelperService = {
+ isFolderType: function(mediaEntity) {
+ if (!mediaEntity) {
+ throw "mediaEntity is null";
+ }
+ if (!mediaEntity.contentTypeAlias) {
+ throw "mediaEntity.contentTypeAlias is null";
+ }
+
+ //if you create a media type, which has an alias that ends with ...Folder then its a folder: ex: "secureFolder", "bannerFolder", "Folder"
+ //this is the exact same logic that is performed in MediaController.GetChildFolders
+ return mediaEntity.contentTypeAlias.endsWith("Folder");
+ },
+
getAllowedImagetypes: function (mediaId){
// Get All allowedTypes
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
index 16c5efe799..d09b04f97a 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.html
@@ -51,7 +51,7 @@
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js
index be1c5856ae..b8ba4f880b 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/layouts/grid/grid.listviewlayout.controller.js
@@ -37,7 +37,8 @@
function activate() {
vm.itemsWithoutFolders = filterOutFolders($scope.items);
- if($scope.entityType === 'media') {
+ //no need to make another REST/DB call if this data is not used when we are browsing the bin
+ if ($scope.entityType === 'media' && !vm.isRecycleBin) {
mediaTypeHelper.getAllowedImagetypes(vm.nodeId).then(function (types) {
vm.acceptedMediatypes = types;
});
diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
index 0a1a14fc44..f8887c6c44 100644
--- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/listview/listview.controller.js
@@ -53,7 +53,9 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
$scope.isNew = false;
$scope.actionInProgress = false;
$scope.selection = [];
- $scope.folders = [];
+ $scope.folders = [];
+ //tracks if we've already loaded the folders for the current node
+ var foldersLoaded = false;
$scope.listViewResultSet = {
totalPages: 0,
items: []
@@ -268,12 +270,13 @@ function listViewController($rootScope, $scope, $routeParams, $injector, $cookie
});
}
- if ($scope.entityType === 'media') {
-
+ if (!foldersLoaded && $scope.entityType === 'media') {
+ //The folders aren't loaded - we only need to do this once since we're never changing node ids
mediaResource.getChildFolders($scope.contentId)
.then(function (folders) {
$scope.folders = folders;
$scope.viewLoaded = true;
+ foldersLoaded = true;
});
} else {
diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs
index fa3e21a1eb..cd8e91274f 100644
--- a/src/Umbraco.Web/Editors/EntityController.cs
+++ b/src/Umbraco.Web/Editors/EntityController.cs
@@ -4,29 +4,16 @@ using System.Globalization;
using System.Net;
using System.Text;
using System.Web.Http;
-using System.Web.Http.ModelBinding;
using AutoMapper;
-using ClientDependency.Core;
-using Examine.LuceneEngine;
-using Examine.LuceneEngine.Providers;
-using Newtonsoft.Json;
using Umbraco.Core;
-using Umbraco.Core.Logging;
using Umbraco.Core.Models.Membership;
-using Umbraco.Core.Services;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Mvc;
using System.Linq;
-using Umbraco.Core.Models.EntityBase;
using Umbraco.Core.Models;
-using Umbraco.Web.WebApi.Filters;
-using umbraco.cms.businesslogic.packager;
using Constants = Umbraco.Core.Constants;
using Examine;
-using Examine.LuceneEngine.SearchCriteria;
-using Examine.SearchCriteria;
using Umbraco.Web.Dynamics;
-using umbraco;
using System.Text.RegularExpressions;
using Umbraco.Core.Xml;
@@ -222,6 +209,17 @@ namespace Umbraco.Web.Editors
return GetResultForChildren(id, type);
}
+ ///
+ /// Get paged descendant entities by id
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
public IEnumerable GetAncestors(int id, UmbracoEntityTypes type)
{
return GetResultForAncestors(id, type);
diff --git a/src/Umbraco.Web/Editors/MediaController.cs b/src/Umbraco.Web/Editors/MediaController.cs
index 77ab9ff6e5..82ddfe3fa9 100644
--- a/src/Umbraco.Web/Editors/MediaController.cs
+++ b/src/Umbraco.Web/Editors/MediaController.cs
@@ -5,37 +5,28 @@ using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Http.Formatting;
-using System.Security.AccessControl;
using System.Text;
using System.Threading.Tasks;
-using System.Web;
using System.Web.Http;
using System.Web.Http.ModelBinding;
using AutoMapper;
using Umbraco.Core;
-using Umbraco.Core.Dynamics;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
using Umbraco.Core.Models;
-using Umbraco.Core.Models.Editors;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
using Umbraco.Core.Services;
-using Umbraco.Web.Models;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Mapping;
using Umbraco.Web.Mvc;
using Umbraco.Web.WebApi;
using System.Linq;
-using System.Runtime.Serialization;
using System.Web.Http.Controllers;
using Umbraco.Web.WebApi.Binders;
using Umbraco.Web.WebApi.Filters;
-using umbraco;
-using umbraco.BusinessLogic.Actions;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Configuration;
-using Umbraco.Core.Persistence.FaultHandling;
using Umbraco.Web.UI;
using Notification = Umbraco.Web.Models.ContentEditing.Notification;
using Umbraco.Core.Persistence;
@@ -160,19 +151,48 @@ namespace Umbraco.Web.Editors
}
///
- /// Returns media items known to be a container of other media items
+ /// Returns media items known to be of a "Folder" type
///
///
///
+ [Obsolete("This is no longer used and shouldn't be because it performs poorly when there are a lot of media items")]
[FilterAllowedOutgoingMedia(typeof(IEnumerable>))]
public IEnumerable> GetChildFolders(int id = -1)
+ {
+ //we are only allowing a max of 500 to be returned here, if more is required it needs to be paged
+ var result = GetChildFolders(id, 1, 500);
+ return result.Items;
+ }
+
+ ///
+ /// Returns a paged result of media items known to be of a "Folder" type
+ ///
+ ///
+ ///
+ ///
+ ///
+ public PagedResult> GetChildFolders(int id, int pageNumber, int pageSize)
{
//Suggested convention for folder mediatypes - we can make this more or less complicated as long as we document it...
//if you create a media type, which has an alias that ends with ...Folder then its a folder: ex: "secureFolder", "bannerFolder", "Folder"
- var folderTypes = Services.ContentTypeService.GetAllMediaTypes().ToArray().Where(x => x.Alias.EndsWith("Folder")).Select(x => x.Id);
+ var folderTypes = Services.ContentTypeService
+ .GetAllMediaTypes()
+ .Where(x => x.Alias.EndsWith("Folder"))
+ .Select(x => x.Id)
+ .ToArray();
- var children = (id < 0) ? Services.MediaService.GetRootMedia() : Services.MediaService.GetById(id).Children();
- return children.Where(x => folderTypes.Contains(x.ContentTypeId)).Select(Mapper.Map>);
+ if (folderTypes.Length == 0)
+ {
+ return new PagedResult>(0, pageNumber, pageSize);
+ }
+
+ long total;
+ var children = Services.MediaService.GetPagedChildren(id, pageNumber - 1, pageSize, out total, "Name", Direction.Ascending, true, null, folderTypes.ToArray());
+
+ return new PagedResult>(total, pageNumber, pageSize)
+ {
+ Items = children.Select(Mapper.Map>)
+ };
}
///