From 59cb1ad31e6bbf7c5b8da7f5d206cd735d5f3bdb Mon Sep 17 00:00:00 2001 From: Sebastiaan Janssen Date: Thu, 8 May 2014 16:08:16 +0200 Subject: [PATCH] Revert "Fixes: U4-4211 User without media section permission will be logged out immediately when accessing a document type using a media picker datatype (u7.0.3) - this is done by using the entityResource in the mediaPicker but to do this we need to return a cut down version of the media properties in the additionalData which is tricky because the cropper stores json which is ntext and the existing sql didn't cater for this. This also cleans up the entity service and we no longer have this internal collection of properties, everything is just added to additionalData, then had to add mediaHelper method to deal with getting urls from a media 'entity' not just a media object." This reverts commit c38c2ede11158686edd30d5a422da15ba21ec99b. --- src/Umbraco.Core/Models/UmbracoEntity.cs | 34 +-- .../Factories/UmbracoEntityFactory.cs | 15 +- .../Repositories/EntityRepository.cs | 211 ++++++------------ src/Umbraco.Core/StringExtensions.cs | 23 -- .../Models/UmbracoEntityTests.cs | 15 +- .../Services/EntityServiceTests.cs | 22 +- .../common/services/mediahelper.service.js | 79 ++----- .../fileupload/fileupload.controller.js | 6 +- .../imagecropper/imagecropper.controller.js | 6 +- .../mediapicker/mediapicker.controller.js | 28 +-- src/Umbraco.Web/Editors/EntityController.cs | 3 +- src/Umbraco.Web/Editors/ImagesController.cs | 2 - .../WebServices/FolderBrowserService.cs | 11 +- .../umbraco/Trees/BaseMediaTree.cs | 115 +++++----- 14 files changed, 192 insertions(+), 378 deletions(-) diff --git a/src/Umbraco.Core/Models/UmbracoEntity.cs b/src/Umbraco.Core/Models/UmbracoEntity.cs index 23a6bcfe5b..92bdf3c790 100644 --- a/src/Umbraco.Core/Models/UmbracoEntity.cs +++ b/src/Umbraco.Core/Models/UmbracoEntity.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Reflection; -using System.Runtime.CompilerServices; using Umbraco.Core.Models.EntityBase; namespace Umbraco.Core.Models @@ -48,11 +47,13 @@ namespace Umbraco.Core.Models public UmbracoEntity() { AdditionalData = new Dictionary(); + UmbracoProperties = new List(); } public UmbracoEntity(bool trashed) { AdditionalData = new Dictionary(); + UmbracoProperties = new List(); Trashed = trashed; } @@ -60,6 +61,7 @@ namespace Umbraco.Core.Models public UmbracoEntity(UInt64 trashed) { AdditionalData = new Dictionary(); + UmbracoProperties = new List(); Trashed = trashed == 1; } @@ -285,31 +287,15 @@ namespace Umbraco.Core.Models } } - public override object DeepClone() - { - var clone = (UmbracoEntity) base.DeepClone(); - - //This ensures that any value in the dictionary that is deep cloneable is cloned too - foreach (var key in clone.AdditionalData.Keys.ToArray()) - { - var deepCloneable = clone.AdditionalData[key] as IDeepCloneable; - if (deepCloneable != null) - { - clone.AdditionalData[key] = deepCloneable.DeepClone(); - } - } - - return clone; - } - /// - /// A struction that can be contained in the additional data of an UmbracoEntity representing - /// a user defined property + /// Some entities may expose additional data that other's might not, this custom data will be available in this collection /// - public class EntityProperty : IDeepCloneable + public IList UmbracoProperties { get; set; } + + internal class UmbracoProperty : IDeepCloneable { public string PropertyEditorAlias { get; set; } - public object Value { get; set; } + public string Value { get; set; } public object DeepClone() { //Memberwise clone on Entity will work since it doesn't have any deep elements @@ -318,7 +304,7 @@ namespace Umbraco.Core.Models return clone; } - protected bool Equals(EntityProperty other) + protected bool Equals(UmbracoProperty other) { return PropertyEditorAlias.Equals(other.PropertyEditorAlias) && string.Equals(Value, other.Value); } @@ -328,7 +314,7 @@ namespace Umbraco.Core.Models if (ReferenceEquals(null, obj)) return false; if (ReferenceEquals(this, obj)) return true; if (obj.GetType() != this.GetType()) return false; - return Equals((EntityProperty) obj); + return Equals((UmbracoProperty) obj); } public override int GetHashCode() diff --git a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs index f33ae1af2f..db1a99bc45 100644 --- a/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UmbracoEntityFactory.cs @@ -44,6 +44,7 @@ namespace Umbraco.Core.Persistence.Factories ContentTypeAlias = asDictionary.ContainsKey("alias") ? (d.alias ?? string.Empty) : string.Empty, ContentTypeIcon = asDictionary.ContainsKey("icon") ? (d.icon ?? string.Empty) : string.Empty, ContentTypeThumbnail = asDictionary.ContainsKey("thumbnail") ? (d.thumbnail ?? string.Empty) : string.Empty, + UmbracoProperties = new List() }; var publishedVersion = default(Guid); @@ -86,6 +87,7 @@ namespace Umbraco.Core.Persistence.Factories ContentTypeAlias = dto.Alias ?? string.Empty, ContentTypeIcon = dto.Icon ?? string.Empty, ContentTypeThumbnail = dto.Thumbnail ?? string.Empty, + UmbracoProperties = new List() }; entity.IsPublished = dto.PublishedVersion != default(Guid) || (dto.NewestVersion != default(Guid) && dto.PublishedVersion == dto.NewestVersion); @@ -96,13 +98,12 @@ namespace Umbraco.Core.Persistence.Factories { foreach (var propertyDto in dto.UmbracoPropertyDtos) { - entity.AdditionalData[propertyDto.PropertyAlias] = new UmbracoEntity.EntityProperty - { - PropertyEditorAlias = propertyDto.PropertyEditorAlias, - Value = propertyDto.NTextValue.IsNullOrWhiteSpace() - ? propertyDto.NVarcharValue - : propertyDto.NTextValue.ConvertToJsonIfPossible() - }; + entity.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty + { + PropertyEditorAlias = + propertyDto.PropertyEditorAlias, + Value = propertyDto.UmbracoFile + }); } } diff --git a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs index 5f721f7141..7336e36ab7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/EntityRepository.cs @@ -66,31 +66,15 @@ namespace Umbraco.Core.Persistence.Repositories { bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key).Append(GetGroupBy(isContent, isMedia)); + var nodeDto = _work.Database.FirstOrDefault(sql); + if (nodeDto == null) + return null; - var sql = GetFullSqlForEntityType(key, isContent, isMedia, objectTypeId); - - if (isMedia) - { - //for now treat media differently - //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, sql); + var factory = new UmbracoEntityFactory(); + var entity = factory.BuildEntityFromDynamic(nodeDto); - return entities.FirstOrDefault(); - } - else - { - var nodeDto = _work.Database.FirstOrDefault(sql); - if (nodeDto == null) - return null; - - var factory = new UmbracoEntityFactory(); - var entity = factory.BuildEntityFromDynamic(nodeDto); - - return entity; - } - - + return entity; } public virtual IUmbracoEntity Get(int id) @@ -110,31 +94,16 @@ namespace Umbraco.Core.Persistence.Repositories { bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); + var sql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id).Append(GetGroupBy(isContent, isMedia)); - var sql = GetFullSqlForEntityType(id, isContent, isMedia, objectTypeId); - - if (isMedia) - { - //for now treat media differently - //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields - var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, sql); + var nodeDto = _work.Database.FirstOrDefault(sql); + if (nodeDto == null) + return null; - return entities.FirstOrDefault(); - } - else - { - var nodeDto = _work.Database.FirstOrDefault(sql); - if (nodeDto == null) - return null; + var factory = new UmbracoEntityFactory(); + var entity = factory.BuildEntityFromDynamic(nodeDto); - var factory = new UmbracoEntityFactory(); - var entity = factory.BuildEntityFromDynamic(nodeDto); - - return entity; - } - - + return entity; } public virtual IEnumerable GetAll(Guid objectTypeId, params int[] ids) @@ -150,8 +119,8 @@ namespace Umbraco.Core.Persistence.Repositories { bool isContent = objectTypeId == new Guid(Constants.ObjectTypes.Document); bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); - var sql = GetFullSqlForEntityType(isContent, isMedia, objectTypeId, string.Empty); - + var sql = GetBaseWhere(GetBase, isContent, isMedia, string.Empty, objectTypeId).Append(GetGroupBy(isContent, isMedia)); + var factory = new UmbracoEntityFactory(); if (isMedia) @@ -197,28 +166,24 @@ namespace Umbraco.Core.Persistence.Repositories bool isMedia = objectTypeId == new Guid(Constants.ObjectTypes.Media); var wheres = string.Concat(" AND ", string.Join(" AND ", ((Query)query).WhereClauses())); - var sqlClause = GetBaseWhere(GetBase, isContent, isMedia, wheres, objectTypeId); - var translator = new SqlTranslator(sqlClause, query); - var entitySql = translator.Translate(); + var sql = translator.Translate().Append(GetGroupBy(isContent, isMedia)); var factory = new UmbracoEntityFactory(); if (isMedia) { - var mediaSql = GetFullSqlForMedia(entitySql, wheres); - //treat media differently for now //TODO: We should really use this methodology for Content/Members too!! since it includes properties and ALL of the dynamic db fields var entities = _work.Database.Fetch( - new UmbracoEntityRelator().Map, mediaSql); + new UmbracoEntityRelator().Map, sql); return entities; } else { //use dynamic so that we can get ALL properties from the SQL so we can chuck that data into our AdditionalData - var dtos = _work.Database.Fetch(entitySql.Append(GetGroupBy(isContent, false))); + var dtos = _work.Database.Fetch(sql); return dtos.Select(factory.BuildEntityFromDynamic).Cast().ToList(); } } @@ -228,62 +193,6 @@ namespace Umbraco.Core.Persistence.Repositories #region Sql Statements - protected Sql GetFullSqlForEntityType(Guid key, bool isContent, bool isMedia, Guid objectTypeId) - { - var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, key); - - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))); - } - - protected Sql GetFullSqlForEntityType(int id, bool isContent, bool isMedia, Guid objectTypeId) - { - var entitySql = GetBaseWhere(GetBase, isContent, isMedia, objectTypeId, id); - - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))); - } - - protected Sql GetFullSqlForEntityType(bool isContent, bool isMedia, Guid objectTypeId, string additionalWhereClause) - { - var entitySql = GetBaseWhere(GetBase, isContent, isMedia, additionalWhereClause, objectTypeId); - - if (isMedia == false) return entitySql.Append(GetGroupBy(isContent, false)); - - return GetFullSqlForMedia(entitySql.Append(GetGroupBy(isContent, true, false))); - } - - private Sql GetFullSqlForMedia(Sql entitySql, string additionWhereStatement = "") - { - //this will add any dataNvarchar property to the output which can be added to the additional properties - - var joinSql = new Sql() - .Select("contentNodeId, versionId, dataNvarchar, dataNtext, propertyEditorAlias, alias as propertyTypeAlias") - .From() - .InnerJoin() - .On(dto => dto.NodeId, dto => dto.NodeId) - .InnerJoin() - .On(dto => dto.Id, dto => dto.PropertyTypeId) - .InnerJoin() - .On(dto => dto.DataTypeId, dto => dto.DataTypeId) - .Where("umbracoNode.nodeObjectType = @nodeObjectType" + additionWhereStatement, new {nodeObjectType = Constants.ObjectTypes.Media}); - - //We're going to create a query to query against the entity SQL - // because we cannot group by nText columns and we have a COUNT in the entitySql we cannot simply left join - // the entitySql query, we have to join the wrapped query to get the ntext in the result - - var wrappedSql = new Sql("SELECT * FROM (") - .Append(entitySql) - .Append(new Sql(") tmpTbl LEFT JOIN (")) - .Append(joinSql) - .Append(new Sql(") as property ON id = property.contentNodeId")) - .OrderBy("sortOrder"); - - return wrappedSql; - } - protected virtual Sql GetBase(bool isContent, bool isMedia, string additionWhereStatement = "") { var columns = new List @@ -312,9 +221,13 @@ namespace Umbraco.Core.Persistence.Repositories columns.Add("contenttype.isContainer"); } - //Creates an SQL query to return a single row for the entity + if (isMedia) + { + columns.Add("property.dataNvarchar as umbracoFile"); + columns.Add("property.propertyEditorAlias"); + } - var entitySql = new Sql() + var sql = new Sql() .Select(columns.ToArray()) .From("umbracoNode umbracoNode") .LeftJoin("umbracoNode parent").On("parent.parentID = umbracoNode.id"); @@ -322,7 +235,7 @@ namespace Umbraco.Core.Persistence.Repositories if (isContent || isMedia) { - entitySql.InnerJoin("cmsContent content").On("content.nodeId = umbracoNode.id") + sql.InnerJoin("cmsContent content").On("content.nodeId = umbracoNode.id") .LeftJoin("cmsContentType contenttype").On("contenttype.nodeId = content.contentType") .LeftJoin( "(SELECT nodeId, versionId FROM cmsDocument WHERE published = 1 GROUP BY nodeId, versionId) as published") @@ -332,7 +245,18 @@ namespace Umbraco.Core.Persistence.Repositories .On("umbracoNode.id = latest.nodeId"); } - return entitySql; + if (isMedia) + { + sql.LeftJoin( + "(SELECT contentNodeId, versionId, dataNvarchar, propertyEditorAlias FROM cmsPropertyData " + + "INNER JOIN umbracoNode ON cmsPropertyData.contentNodeId = umbracoNode.id " + + "INNER JOIN cmsPropertyType ON cmsPropertyType.id = cmsPropertyData.propertytypeid " + + "INNER JOIN cmsDataType ON cmsPropertyType.dataTypeId = cmsDataType.nodeId "+ + "WHERE umbracoNode.nodeObjectType = '" + Constants.ObjectTypes.Media + "'" + additionWhereStatement + ") as property") + .On("umbracoNode.id = property.contentNodeId"); + } + + return sql; } protected virtual Sql GetBaseWhere(Func baseQuery, bool isContent, bool isMedia, string additionWhereStatement, Guid nodeObjectType) @@ -374,7 +298,7 @@ namespace Umbraco.Core.Persistence.Repositories return sql; } - protected virtual Sql GetGroupBy(bool isContent, bool isMedia, bool includeSort = true) + protected virtual Sql GetGroupBy(bool isContent, bool isMedia) { var columns = new List { @@ -400,18 +324,19 @@ namespace Umbraco.Core.Persistence.Repositories columns.Add("contenttype.thumbnail"); columns.Add("contenttype.isContainer"); } - - var sql = new Sql() - .GroupBy(columns.ToArray()); - if (includeSort) + if (isMedia) { - sql = sql.OrderBy("umbracoNode.sortOrder"); + columns.Add("property.dataNvarchar"); + columns.Add("property.propertyEditorAlias"); } + var sql = new Sql() + .GroupBy(columns.ToArray()) + .OrderBy("umbracoNode.sortOrder"); return sql; } - + #endregion /// @@ -452,21 +377,15 @@ namespace Umbraco.Core.Persistence.Repositories [ResultColumn] public List UmbracoPropertyDtos { get; set; } } - + [ExplicitColumns] internal class UmbracoPropertyDto { [Column("propertyEditorAlias")] public string PropertyEditorAlias { get; set; } - [Column("propertyTypeAlias")] - public string PropertyAlias { get; set; } - - [Column("dataNvarchar")] - public string NVarcharValue { get; set; } - - [Column("dataNtext")] - public string NTextValue { get; set; } + [Column("umbracoFile")] + public string UmbracoFile { get; set; } } /// @@ -493,15 +412,16 @@ namespace Umbraco.Core.Persistence.Repositories // Is this the same UmbracoEntity as the current one we're processing if (Current != null && Current.Key == a.uniqueID) { - // Add this UmbracoProperty to the current additional data - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty + // Yes, just add this UmbracoProperty to the current UmbracoEntity's collection + if (Current.UmbracoProperties == null) { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() - }; - + Current.UmbracoProperties = new List(); + } + Current.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty + { + PropertyEditorAlias = p.PropertyEditorAlias, + Value = p.UmbracoFile + }); // Return null to indicate we're not done with this UmbracoEntity yet return null; } @@ -517,13 +437,14 @@ namespace Umbraco.Core.Persistence.Repositories Current = _factory.BuildEntityFromDynamic(a); //add the property/create the prop list if null - Current.AdditionalData[p.PropertyAlias] = new UmbracoEntity.EntityProperty - { - PropertyEditorAlias = p.PropertyEditorAlias, - Value = p.NTextValue.IsNullOrWhiteSpace() - ? p.NVarcharValue - : p.NTextValue.ConvertToJsonIfPossible() - }; + Current.UmbracoProperties = new List + { + new UmbracoEntity.UmbracoProperty + { + PropertyEditorAlias = p.PropertyEditorAlias, + Value = p.UmbracoFile + } + }; // Return the now populated previous UmbracoEntity (or null if first time through) return prev; diff --git a/src/Umbraco.Core/StringExtensions.cs b/src/Umbraco.Core/StringExtensions.cs index d1b20cce30..395f9cea0c 100644 --- a/src/Umbraco.Core/StringExtensions.cs +++ b/src/Umbraco.Core/StringExtensions.cs @@ -10,7 +10,6 @@ using System.Text; using System.Text.RegularExpressions; using System.Web; using System.Xml; -using Newtonsoft.Json; using Umbraco.Core.Configuration; using System.Web.Security; using Umbraco.Core.Strings; @@ -53,28 +52,6 @@ namespace Umbraco.Core || (input.StartsWith("[") && input.EndsWith("]")); } - /// - /// Returns a JObject/JArray instance if the string can be converted to json, otherwise returns the string - /// - /// - /// - internal static object ConvertToJsonIfPossible(this string input) - { - if (input.DetectIsJson() == false) - { - return input; - } - try - { - var obj = JsonConvert.DeserializeObject(input); - return obj; - } - catch (Exception ex) - { - return input; - } - } - internal static string ReplaceNonAlphanumericChars(this string input, char replacement) { //any character that is not alphanumeric, convert to a hyphen diff --git a/src/Umbraco.Tests/Models/UmbracoEntityTests.cs b/src/Umbraco.Tests/Models/UmbracoEntityTests.cs index 52513d551d..ac70364e67 100644 --- a/src/Umbraco.Tests/Models/UmbracoEntityTests.cs +++ b/src/Umbraco.Tests/Models/UmbracoEntityTests.cs @@ -47,13 +47,12 @@ namespace Umbraco.Tests.Models }; item.AdditionalData.Add("test1", 3); item.AdditionalData.Add("test2", "valuie"); - - item.AdditionalData.Add("test3", new UmbracoEntity.EntityProperty() + item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty() { Value = "test", PropertyEditorAlias = "TestPropertyEditor" }); - item.AdditionalData.Add("test4", new UmbracoEntity.EntityProperty() + item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty() { Value = "test2", PropertyEditorAlias = "TestPropertyEditor2" @@ -83,6 +82,12 @@ namespace Umbraco.Tests.Models Assert.AreEqual(clone.UpdateDate, item.UpdateDate); Assert.AreEqual(clone.AdditionalData.Count, item.AdditionalData.Count); Assert.AreEqual(clone.AdditionalData, item.AdditionalData); + Assert.AreEqual(clone.UmbracoProperties.Count, item.UmbracoProperties.Count); + for (var i = 0; i < clone.UmbracoProperties.Count; i++) + { + Assert.AreNotSame(clone.UmbracoProperties[i], item.UmbracoProperties[i]); + Assert.AreEqual(clone.UmbracoProperties[i], item.UmbracoProperties[i]); + } //This double verifies by reflection var allProps = clone.GetType().GetProperties(); @@ -120,12 +125,12 @@ namespace Umbraco.Tests.Models }; item.AdditionalData.Add("test1", 3); item.AdditionalData.Add("test2", "valuie"); - item.AdditionalData.Add("test3", new UmbracoEntity.EntityProperty() + item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty() { Value = "test", PropertyEditorAlias = "TestPropertyEditor" }); - item.AdditionalData.Add("test4", new UmbracoEntity.EntityProperty() + item.UmbracoProperties.Add(new UmbracoEntity.UmbracoProperty() { Value = "test2", PropertyEditorAlias = "TestPropertyEditor2" diff --git a/src/Umbraco.Tests/Services/EntityServiceTests.cs b/src/Umbraco.Tests/Services/EntityServiceTests.cs index 9826e9fc3f..82cc2c7560 100644 --- a/src/Umbraco.Tests/Services/EntityServiceTests.cs +++ b/src/Umbraco.Tests/Services/EntityServiceTests.cs @@ -32,7 +32,7 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetAll(UmbracoObjectTypes.Document).ToArray(); + var entities = service.GetAll(UmbracoObjectTypes.Document); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(4)); @@ -45,7 +45,7 @@ namespace Umbraco.Tests.Services var service = ServiceContext.EntityService; var objectTypeId = new Guid(Constants.ObjectTypes.Document); - var entities = service.GetAll(objectTypeId).ToArray(); + var entities = service.GetAll(objectTypeId); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(4)); @@ -57,7 +57,7 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetAll().ToArray(); + var entities = service.GetAll(); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(4)); @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetChildren(-1, UmbracoObjectTypes.Document).ToArray(); + var entities = service.GetChildren(-1, UmbracoObjectTypes.Document); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(1)); @@ -92,7 +92,7 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetAll(UmbracoObjectTypes.DocumentType).ToArray(); + var entities = service.GetAll(UmbracoObjectTypes.DocumentType); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(1)); @@ -104,7 +104,7 @@ namespace Umbraco.Tests.Services var service = ServiceContext.EntityService; var objectTypeId = new Guid(Constants.ObjectTypes.DocumentType); - var entities = service.GetAll(objectTypeId).ToArray(); + var entities = service.GetAll(objectTypeId); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(1)); @@ -115,7 +115,7 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetAll().ToArray(); + var entities = service.GetAll(); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(1)); @@ -126,16 +126,16 @@ namespace Umbraco.Tests.Services { var service = ServiceContext.EntityService; - var entities = service.GetAll(UmbracoObjectTypes.Media).ToArray(); + var entities = service.GetAll(UmbracoObjectTypes.Media); Assert.That(entities.Any(), Is.True); Assert.That(entities.Count(), Is.EqualTo(3)); - + //Assert.That(entities.Any(x => ((UmbracoEntity)x).UmbracoFile != string.Empty), Is.True); Assert.That( entities.Any( x => - x.AdditionalData.Any(y => y.Value is UmbracoEntity.EntityProperty - && ((UmbracoEntity.EntityProperty)y.Value).PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)), Is.True); + ((UmbracoEntity) x).UmbracoProperties.Any( + y => y.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)), Is.True); } private static bool _isSetup = false; diff --git a/src/Umbraco.Web.UI.Client/src/common/services/mediahelper.service.js b/src/Umbraco.Web.UI.Client/src/common/services/mediahelper.service.js index 67dbcecc54..2e06bc1656 100644 --- a/src/Umbraco.Web.UI.Client/src/common/services/mediahelper.service.js +++ b/src/Umbraco.Web.UI.Client/src/common/services/mediahelper.service.js @@ -129,79 +129,30 @@ function mediaHelper(umbRequestHelper) { _mediaFileResolvers[propertyEditorAlias] = func; }, - /** - * @ngdoc function - * @name umbraco.services.mediaHelper#resolveFileFromEntity - * @methodOf umbraco.services.mediaHelper - * @function - * - * @description - * Gets the media file url for a media entity returned with the entityResource - * - * @param {object} mediaEntity A media Entity returned from the entityResource - * @param {boolean} thumbnail Whether to return the thumbnail url or normal url - */ - resolveFileFromEntity : function(mediaEntity, thumbnail) { - - if (!angular.isObject(mediaEntity.metaData)) { - throw "Cannot resolve the file url from the mediaEntity, it does not contain the required metaData"; - } - - var values = _.values(mediaEntity.metaData); - for (var i = 0; i < values.length; i++) { - var val = values[i]; - if (angular.isObject(val) && val.PropertyEditorAlias) { - for (var resolver in _mediaFileResolvers) { - if (val.PropertyEditorAlias === resolver) { - //we need to format a property variable that coincides with how the property would be structured - // if it came from the mediaResource just to keep things slightly easier for the file resolvers. - var property = { value: val.Value }; - - return _mediaFileResolvers[resolver](property, mediaEntity, thumbnail); - } - } - } - } - - return ""; - }, - - /** - * @ngdoc function - * @name umbraco.services.mediaHelper#resolveFile - * @methodOf umbraco.services.mediaHelper - * @function - * - * @description - * Gets the media file url for a media object returned with the mediaResource - * - * @param {object} mediaEntity A media Entity returned from the entityResource - * @param {boolean} thumbnail Whether to return the thumbnail url or normal url - */ /*jshint loopfunc: true */ resolveFile : function(mediaItem, thumbnail){ - - function iterateProps(props){ - var res = null; + var _props = []; + function _iterateProps(props){ + var result = null; for(var resolver in _mediaFileResolvers) { - var property = _.find(props, function(prop){ return prop.editor === resolver; }); + var property = _.find(props, function(property){ return property.editor === resolver; }); if(property){ - res = _mediaFileResolvers[resolver](property, mediaItem, thumbnail); + result = _mediaFileResolvers[resolver](property, mediaItem, thumbnail); break; } } - return res; + return result; } //we either have properties raw on the object, or spread out on tabs var result = ""; if(mediaItem.properties){ - result = iterateProps(mediaItem.properties); + result = _iterateProps(mediaItem.properties); }else if(mediaItem.tabs){ for(var tab in mediaItem.tabs) { if(mediaItem.tabs[tab].properties){ - result = iterateProps(mediaItem.tabs[tab].properties); + result = _iterateProps(mediaItem.tabs[tab].properties); if(result){ break; } @@ -213,26 +164,26 @@ function mediaHelper(umbRequestHelper) { /*jshint loopfunc: true */ hasFilePropertyType : function(mediaItem){ - function iterateProps(props){ - var res = false; + function _iterateProps(props){ + var result = false; for(var resolver in _mediaFileResolvers) { - var property = _.find(props, function(prop){ return prop.editor === resolver; }); + var property = _.find(props, function(property){ return property.editor === resolver; }); if(property){ - res = true; + result = true; break; } } - return res; + return result; } //we either have properties raw on the object, or spread out on tabs var result = false; if(mediaItem.properties){ - result = iterateProps(mediaItem.properties); + result = _iterateProps(mediaItem.properties); }else if(mediaItem.tabs){ for(var tab in mediaItem.tabs) { if(mediaItem.tabs[tab].properties){ - result = iterateProps(mediaItem.tabs[tab].properties); + result = _iterateProps(mediaItem.tabs[tab].properties); if(result){ break; } diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js index 7aa65473a6..0224853e7b 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/fileupload/fileupload.controller.js @@ -125,15 +125,11 @@ function fileUploadController($scope, $element, $compile, imageHelper, fileManag angular.module("umbraco") .controller('Umbraco.PropertyEditors.FileUploadController', fileUploadController) .run(function(mediaHelper, umbRequestHelper){ - if (mediaHelper && mediaHelper.registerFileResolver) { - - //NOTE: The 'entity' can be either a normal media entity or an "entity" returned from the entityResource - // they contain different data structures so if we need to query against it we need to be aware of this. + if(mediaHelper && mediaHelper.registerFileResolver){ mediaHelper.registerFileResolver("Umbraco.UploadField", function(property, entity, thumbnail){ if (thumbnail) { if (mediaHelper.detectIfImageByExtension(property.value)) { - var thumbnailUrl = umbRequestHelper.getApiUrl( "imagesApiBaseUrl", "GetBigThumbnail", diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js index 7189ca504a..abcdb0852f 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/imagecropper/imagecropper.controller.js @@ -98,14 +98,11 @@ angular.module('umbraco') }) .run(function (mediaHelper, umbRequestHelper) { if (mediaHelper && mediaHelper.registerFileResolver) { - - //NOTE: The 'entity' can be either a normal media entity or an "entity" returned from the entityResource - // they contain different data structures so if we need to query against it we need to be aware of this. mediaHelper.registerFileResolver("Umbraco.ImageCropper", function (property, entity, thumbnail) { if (property.value.src) { if (thumbnail === true) { - return property.value.src + "?width=500&mode=max"; + return property.value.src + "?width=600&mode=max"; } else { return property.value.src; @@ -117,7 +114,6 @@ angular.module('umbraco') if (thumbnail) { if (mediaHelper.detectIfImageByExtension(property.value)) { - var thumbnailUrl = umbRequestHelper.getApiUrl( "imagesApiBaseUrl", "GetBigThumbnail", diff --git a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js index 0a1066cda3..e17a03473c 100644 --- a/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/propertyeditors/mediapicker/mediapicker.controller.js @@ -1,7 +1,7 @@ //this controller simply tells the dialogs service to open a mediaPicker window //with a specified callback, this callback will receive an object with a selection on it angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerController", - function ($rootScope, $scope, dialogService, entityResource, mediaResource, mediaHelper, $timeout) { + function($rootScope, $scope, dialogService, mediaResource, mediaHelper, $timeout) { //check the pre-values for multi-picker var multiPicker = $scope.model.config.multiPicker && $scope.model.config.multiPicker !== '0' ? true : false; @@ -17,24 +17,18 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl if ($scope.model.value) { var ids = $scope.model.value.split(','); - //NOTE: We need to use the entityResource NOT the mediaResource here because - // the mediaResource has server side auth configured for which the user must have - // access to the media section, if they don't they'll get auth errors. The entityResource - // acts differently in that it allows access if the user has access to any of the apps that - // might require it's use. Therefore we need to use the metatData property to get at the thumbnail - // value. - - entityResource.getByIds(ids, "Media").then(function (medias) { - + mediaResource.getByIds(ids).then(function (medias) { + //img.media = media; _.each(medias, function (media, i) { //only show non-trashed items - if (media.parentId >= -1) { - - if (!media.thumbnail) { - media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); + if(media.parentId >= -1){ + if(!media.thumbnail){ + media.thumbnail = mediaHelper.resolveFile(media, true); } + //media.src = mediaHelper.getImagePropertyValue({ imageModel: media }); + //media.thumbnail = mediaHelper.getThumbnailFromPath(media.src); $scope.images.push(media); $scope.ids.push(media.id); } @@ -66,10 +60,10 @@ angular.module('umbraco').controller("Umbraco.PropertyEditors.MediaPickerControl _.each(data, function(media, i) { - if (!media.thumbnail) { - media.thumbnail = mediaHelper.resolveFileFromEntity(media, true); + if(!media.thumbnail){ + media.thumbnail = mediaHelper.resolveFile(media, true); } - + $scope.images.push(media); $scope.ids.push(media.id); }); diff --git a/src/Umbraco.Web/Editors/EntityController.cs b/src/Umbraco.Web/Editors/EntityController.cs index 507c229122..52d60e566f 100644 --- a/src/Umbraco.Web/Editors/EntityController.cs +++ b/src/Umbraco.Web/Editors/EntityController.cs @@ -531,9 +531,8 @@ namespace Umbraco.Web.Editors var objectType = ConvertToObjectType(entityType); if (objectType.HasValue) { - var result = ids.Select(id => Mapper.Map(Services.EntityService.Get(id, objectType.Value))) + return ids.Select(id => Mapper.Map(Services.EntityService.Get(id, objectType.Value))) .WhereNotNull(); - return result; } //now we need to convert the unknown ones switch (entityType) diff --git a/src/Umbraco.Web/Editors/ImagesController.cs b/src/Umbraco.Web/Editors/ImagesController.cs index 54938be76d..39b872af6d 100644 --- a/src/Umbraco.Web/Editors/ImagesController.cs +++ b/src/Umbraco.Web/Editors/ImagesController.cs @@ -104,8 +104,6 @@ namespace Umbraco.Web.Editors return GetResized(imagePath, width, Convert.ToString(width)); } - //TODO: We should delegate this to ImageProcessing - /// /// Gets a resized image - if the requested max width is greater than the original image, only the original image will be returned. /// diff --git a/src/Umbraco.Web/WebServices/FolderBrowserService.cs b/src/Umbraco.Web/WebServices/FolderBrowserService.cs index bf5a3f1bd5..2c8cff527d 100644 --- a/src/Umbraco.Web/WebServices/FolderBrowserService.cs +++ b/src/Umbraco.Web/WebServices/FolderBrowserService.cs @@ -32,14 +32,9 @@ namespace Umbraco.Web.WebServices var entities = service.GetChildren(parentId, UmbracoObjectTypes.Media); foreach (UmbracoEntity entity in entities) { - var uploadFieldProperty = entity.AdditionalData - .Select(x => x.Value as UmbracoEntity.EntityProperty) - .Where(x => x != null) - .FirstOrDefault(x => x.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias); - - //var uploadFieldProperty = entity.UmbracoProperties.FirstOrDefault(x => x.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias); - - var thumbnailUrl = uploadFieldProperty == null ? "" : ThumbnailProvidersResolver.Current.GetThumbnailUrl((string)uploadFieldProperty.Value); + var uploadFieldProperty = entity.UmbracoProperties.FirstOrDefault(x => x.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias); + + var thumbnailUrl = uploadFieldProperty == null ? "" : ThumbnailProvidersResolver.Current.GetThumbnailUrl(uploadFieldProperty.Value); var item = new { diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs index f72457d867..0b48f7a2e1 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseMediaTree.cs @@ -21,28 +21,28 @@ namespace umbraco.cms.presentation.Trees { [Obsolete("This is no longer used and will be removed from the codebase in the future")] - public abstract class BaseMediaTree : BaseTree - { + public abstract class BaseMediaTree : BaseTree + { private User _user; - public BaseMediaTree(string application) - : base(application) - { - - } - - /// - /// Returns the current User. This ensures that we don't instantiate a new User object - /// each time. - /// - protected User CurrentUser - { - get - { - return (_user == null ? (_user = UmbracoEnsuredPage.CurrentUser) : _user); - } - } + public BaseMediaTree(string application) + : base(application) + { + + } + /// + /// Returns the current User. This ensures that we don't instantiate a new User object + /// each time. + /// + protected User CurrentUser + { + get + { + return (_user == null ? (_user = UmbracoEnsuredPage.CurrentUser) : _user); + } + } + public override void RenderJS(ref StringBuilder Javascript) { if (!string.IsNullOrEmpty(this.FunctionToCall)) @@ -54,7 +54,7 @@ namespace umbraco.cms.presentation.Trees else if (!this.IsDialog) { Javascript.Append( - @" + @" function openMedia(id) { " + ClientTools.Scripts.GetContentFrame() + ".location.href = 'editMedia.aspx?id=' + id;" + @" } @@ -98,12 +98,12 @@ function openMedia(id) { // to call so that is fine. var entities = Services.EntityService.GetChildren(m_id, UmbracoObjectTypes.Media).ToArray(); - + foreach (UmbracoEntity entity in entities) { var e = entity; var xNode = PerformNodeRender(e.Id, entity.Name, e.HasChildren, e.ContentTypeIcon, e.ContentTypeAlias, () => GetLinkValue(e)); - + OnBeforeNodeRender(ref tree, ref xNode, EventArgs.Empty); if (xNode != null) { @@ -111,7 +111,7 @@ function openMedia(id) { OnAfterNodeRender(ref tree, ref xNode, EventArgs.Empty); } } - } + } } private XmlTreeNode PerformNodeRender(int nodeId, string nodeName, bool hasChildren, string icon, string contentTypeAlias, Func getLinkValue) @@ -164,28 +164,28 @@ function openMedia(id) { return xNode; } - + /// - /// Returns the value for a link in WYSIWYG mode, by default only media items that have a - /// DataTypeUploadField are linkable, however, a custom tree can be created which overrides - /// this method, or another GUID for a custom data type can be added to the LinkableMediaDataTypes - /// list on application startup. - /// - /// - /// - /// + /// Returns the value for a link in WYSIWYG mode, by default only media items that have a + /// DataTypeUploadField are linkable, however, a custom tree can be created which overrides + /// this method, or another GUID for a custom data type can be added to the LinkableMediaDataTypes + /// list on application startup. + /// + /// + /// + /// public virtual string GetLinkValue(Media dd, string nodeLink) { var props = dd.GenericProperties; - foreach (Property p in props) - { - Guid currId = p.PropertyType.DataTypeDefinition.DataType.Id; - if (LinkableMediaDataTypes.Contains(currId) && string.IsNullOrEmpty(p.Value.ToString()) == false) - { - return p.Value.ToString(); - } - } + foreach (Property p in props) + { + Guid currId = p.PropertyType.DataTypeDefinition.DataType.Id; + if (LinkableMediaDataTypes.Contains(currId) && string.IsNullOrEmpty(p.Value.ToString()) == false) + { + return p.Value.ToString(); + } + } return ""; } @@ -200,34 +200,29 @@ function openMedia(id) { /// internal virtual string GetLinkValue(UmbracoEntity entity) { - foreach (var property in entity.AdditionalData - .Select(x => x.Value as UmbracoEntity.EntityProperty) - .Where(x => x != null)) + foreach (var property in entity.UmbracoProperties) { - - //required for backwards compatibility with v7 with changing the GUID -> alias var controlId = LegacyPropertyEditorIdToAliasConverter.GetLegacyIdFromAlias(property.PropertyEditorAlias, LegacyPropertyEditorIdToAliasConverter.NotFoundLegacyIdResponseBehavior.ReturnNull); if (controlId != null) { - if (LinkableMediaDataTypes.Contains(controlId.Value) - && string.IsNullOrEmpty((string)property.Value) == false) - - return property.Value.ToString(); - } + if (LinkableMediaDataTypes.Contains(controlId.Value) && + string.IsNullOrEmpty(property.Value) == false) + return property.Value; + } } return ""; } - /// - /// By default, any media type that is to be "linkable" in the WYSIWYG editor must contain - /// a DataTypeUploadField data type which will ouput the value for the link, however, if - /// a developer wants the WYSIWYG editor to link to a custom media type, they will either have - /// to create their own media tree and inherit from this one and override the GetLinkValue - /// or add another GUID to the LinkableMediaDataType list on application startup that matches - /// the GUID of a custom data type. The order of property types on the media item definition will determine the output value. - /// - public static List LinkableMediaDataTypes { get; protected set; } + /// + /// By default, any media type that is to be "linkable" in the WYSIWYG editor must contain + /// a DataTypeUploadField data type which will ouput the value for the link, however, if + /// a developer wants the WYSIWYG editor to link to a custom media type, they will either have + /// to create their own media tree and inherit from this one and override the GetLinkValue + /// or add another GUID to the LinkableMediaDataType list on application startup that matches + /// the GUID of a custom data type. The order of property types on the media item definition will determine the output value. + /// + public static List LinkableMediaDataTypes { get; protected set; } /// /// Returns true if we can use the EntityService to render the tree or revert to the original way @@ -250,5 +245,5 @@ function openMedia(id) { } } - } + } }