diff --git a/src/Umbraco.Web/IDynamicPublishedContentQuery.cs b/src/Umbraco.Web/IDynamicPublishedContentQuery.cs index 051ba07ff6..7c95fd7e2e 100644 --- a/src/Umbraco.Web/IDynamicPublishedContentQuery.cs +++ b/src/Umbraco.Web/IDynamicPublishedContentQuery.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Xml.XPath; using Umbraco.Core.Xml; @@ -10,15 +11,22 @@ namespace Umbraco.Web public interface IDynamicPublishedContentQuery { dynamic Content(int id); + dynamic Content(Guid id); dynamic ContentSingleAtXPath(string xpath, params XPathVariable[] vars); dynamic ContentSingleAtXPath(XPathExpression xpath, params XPathVariable[] vars); dynamic Content(IEnumerable ids); + dynamic Content(IEnumerable ids); dynamic ContentAtXPath(string xpath, params XPathVariable[] vars); dynamic ContentAtXPath(XPathExpression xpath, params XPathVariable[] vars); dynamic ContentAtRoot(); - + + // note: we CANNOT implement Media by Guid in v7 without break-changing IPublishedCache, + // since we don't support XPath navigation of the media tree. + dynamic Media(int id); + //dynamic Media(Guid id); dynamic Media(IEnumerable ids); + //dynamic Media(IEnumerable ids); dynamic MediaAtRoot(); /// diff --git a/src/Umbraco.Web/ITypedPublishedContentQuery.cs b/src/Umbraco.Web/ITypedPublishedContentQuery.cs index aefe243a0b..7a2be964f7 100644 --- a/src/Umbraco.Web/ITypedPublishedContentQuery.cs +++ b/src/Umbraco.Web/ITypedPublishedContentQuery.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Xml.XPath; using Umbraco.Core.Models; @@ -11,14 +12,21 @@ namespace Umbraco.Web public interface ITypedPublishedContentQuery { IPublishedContent TypedContent(int id); + IPublishedContent TypedContent(Guid id); IPublishedContent TypedContentSingleAtXPath(string xpath, params XPathVariable[] vars); IEnumerable TypedContent(IEnumerable ids); + IEnumerable TypedContent(IEnumerable ids); IEnumerable TypedContentAtXPath(string xpath, params XPathVariable[] vars); IEnumerable TypedContentAtXPath(XPathExpression xpath, params XPathVariable[] vars); IEnumerable TypedContentAtRoot(); + // note: we CANNOT implement TypedMedia by Guid in v7 without break-changing IPublishedCache, + // since we don't support XPath navigation of the media tree. + IPublishedContent TypedMedia(int id); + //IPublishedContent TypedMedia(Guid id); IEnumerable TypedMedia(IEnumerable ids); + //IEnumerable TypedMedia(IEnumerable ids); IEnumerable TypedMediaAtRoot(); /// diff --git a/src/Umbraco.Web/Models/DynamicPublishedContent.cs b/src/Umbraco.Web/Models/DynamicPublishedContent.cs index 26a5517039..141eeefae1 100644 --- a/src/Umbraco.Web/Models/DynamicPublishedContent.cs +++ b/src/Umbraco.Web/Models/DynamicPublishedContent.cs @@ -1101,11 +1101,9 @@ namespace Umbraco.Web.Models } /// - /// A shortcut method for AncestorOrSelf(1) + /// Gets the 'site' content for this content. /// - /// - /// The site homepage - /// + /// The 'site' content ie AncestorOrSelf(1). public DynamicPublishedContent Site() { return AncestorOrSelf(1); diff --git a/src/Umbraco.Web/PublishedContentExtensions.cs b/src/Umbraco.Web/PublishedContentExtensions.cs index 578aab2755..5caa08729a 100644 --- a/src/Umbraco.Web/PublishedContentExtensions.cs +++ b/src/Umbraco.Web/PublishedContentExtensions.cs @@ -1746,6 +1746,17 @@ namespace Umbraco.Web return content.Children().Where(predicate); } + /// + /// Gets the children of the content, of any of the specified types. + /// + /// The content. + /// One or more content type alias. + /// The children of the content, of any of the specified types. + public static IEnumerable Children(this IPublishedContent content, params string[] alias) + { + return content.Children(x => alias.InvariantContains(x.DocumentTypeAlias)); + } + /// /// Gets the children of the content, of a given content type. /// @@ -1853,6 +1864,21 @@ namespace Umbraco.Web #endregion + #region Axes: custom + + // todo: in v8, rename this 'Root' + /// + /// Gets the 'site' content for this content. + /// + /// The content. + /// The 'site' content ie AncestorOrSelf(1). + public static IPublishedContent Site(this IPublishedContent content) + { + return content.AncestorOrSelf(1); + } + + #endregion + #region OfTypes // the .OfType() filter is nice when there's only one type diff --git a/src/Umbraco.Web/PublishedContentQuery.cs b/src/Umbraco.Web/PublishedContentQuery.cs index 16f42b8197..f0f2461ad8 100644 --- a/src/Umbraco.Web/PublishedContentQuery.cs +++ b/src/Umbraco.Web/PublishedContentQuery.cs @@ -2,7 +2,9 @@ using System.Collections.Generic; using System.Linq; using System.Xml.XPath; +using umbraco; using Umbraco.Core; +using Umbraco.Core.Configuration; using Umbraco.Core.Dynamics; using Umbraco.Core.Models; using Umbraco.Core.Xml; @@ -56,6 +58,13 @@ namespace Umbraco.Web : _typedContentQuery.TypedContent(id); } + public IPublishedContent TypedContent(Guid id) + { + return _typedContentQuery == null + ? TypedDocumentById(id, _contentCache) + : _typedContentQuery.TypedContent(id); + } + public IPublishedContent TypedContentSingleAtXPath(string xpath, params XPathVariable[] vars) { return _typedContentQuery == null @@ -70,6 +79,13 @@ namespace Umbraco.Web : _typedContentQuery.TypedContent(ids); } + public IEnumerable TypedContent(IEnumerable ids) + { + return _typedContentQuery == null + ? TypedDocumentsByIds(_contentCache, ids) + : _typedContentQuery.TypedContent(ids); + } + public IEnumerable TypedContentAtXPath(string xpath, params XPathVariable[] vars) { return _typedContentQuery == null @@ -97,7 +113,14 @@ namespace Umbraco.Web ? DocumentById(id, _contentCache, DynamicNull.Null) : _dynamicContentQuery.Content(id); } - + + public dynamic Content(Guid id) + { + return _dynamicContentQuery == null + ? DocumentById(id, _contentCache, DynamicNull.Null) + : _dynamicContentQuery.Content(id); + } + public dynamic ContentSingleAtXPath(string xpath, params XPathVariable[] vars) { return _dynamicContentQuery == null @@ -119,6 +142,13 @@ namespace Umbraco.Web : _dynamicContentQuery.Content(ids); } + public dynamic Content(IEnumerable ids) + { + return _dynamicContentQuery == null + ? DocumentByIds(_contentCache, ids.ToArray()) + : _dynamicContentQuery.Content(ids); + } + public dynamic ContentAtXPath(string xpath, params XPathVariable[] vars) { return _dynamicContentQuery == null @@ -150,7 +180,7 @@ namespace Umbraco.Web ? TypedDocumentById(id, _mediaCache) : _typedContentQuery.TypedMedia(id); } - + public IEnumerable TypedMedia(IEnumerable ids) { return _typedContentQuery == null @@ -196,6 +226,15 @@ namespace Umbraco.Web return doc; } + private IPublishedContent TypedDocumentById(Guid id, ContextualPublishedCache cache) + { + // todo: in v8, implement in a more efficient way + var legacyXml = UmbracoConfig.For.UmbracoSettings().Content.UseLegacyXmlSchema; + var xpath = legacyXml ? "//node [@key=$guid]" : "//* [@isDoc and @key=$guid]"; + var doc = cache.GetSingleByXPath(xpath, new XPathVariable("guid", id.ToString())); + return doc; + } + private IPublishedContent TypedDocumentByXPath(string xpath, XPathVariable[] vars, ContextualPublishedContentCache cache) { var doc = cache.GetSingleByXPath(xpath, vars); @@ -214,6 +253,12 @@ namespace Umbraco.Web return ids.Select(eachId => TypedDocumentById(eachId, cache)).WhereNotNull(); } + private IEnumerable TypedDocumentsByIds(ContextualPublishedCache cache, IEnumerable ids) + { + // todo: in v8, implement in a more efficient way + return ids.Select(eachId => TypedDocumentById(eachId, cache)).WhereNotNull(); + } + private IEnumerable TypedDocumentsByXPath(string xpath, XPathVariable[] vars, ContextualPublishedContentCache cache) { var doc = cache.GetByXPath(xpath, vars); @@ -239,6 +284,14 @@ namespace Umbraco.Web : new DynamicPublishedContent(doc).AsDynamic(); } + private dynamic DocumentById(Guid id, ContextualPublishedCache cache, object ifNotFound) + { + var doc = TypedDocumentById(id, cache); + return doc == null + ? ifNotFound + : new DynamicPublishedContent(doc).AsDynamic(); + } + private dynamic DocumentByXPath(string xpath, XPathVariable[] vars, ContextualPublishedCache cache, object ifNotFound) { var doc = cache.GetSingleByXPath(xpath, vars); @@ -264,6 +317,15 @@ namespace Umbraco.Web return new DynamicPublishedContentList(nodes); } + private dynamic DocumentByIds(ContextualPublishedCache cache, IEnumerable ids) + { + var dNull = DynamicNull.Null; + var nodes = ids.Select(eachId => DocumentById(eachId, cache, dNull)) + .Where(x => TypeHelper.IsTypeAssignableFrom(x) == false) + .Cast(); + return new DynamicPublishedContentList(nodes); + } + private dynamic DocumentsByXPath(string xpath, XPathVariable[] vars, ContextualPublishedCache cache) { return new DynamicPublishedContentList( diff --git a/src/Umbraco.Web/UmbracoHelper.cs b/src/Umbraco.Web/UmbracoHelper.cs index 165b81daba..2508d47b58 100644 --- a/src/Umbraco.Web/UmbracoHelper.cs +++ b/src/Umbraco.Web/UmbracoHelper.cs @@ -15,6 +15,7 @@ using Umbraco.Web.Routing; using Umbraco.Web.Security; using System.Collections.Generic; using System.IO; +using System.Linq; using System.Web.Mvc; using System.Web.Routing; using Umbraco.Core.Cache; @@ -29,10 +30,10 @@ namespace Umbraco.Web private readonly UmbracoContext _umbracoContext; private readonly IPublishedContent _currentPage; private readonly ITypedPublishedContentQuery _typedQuery; - private readonly IDynamicPublishedContentQuery _dynamicQuery; + private readonly IDynamicPublishedContentQuery _dynamicQuery; private readonly HtmlStringUtilities _stringUtilities = new HtmlStringUtilities(); - private IUmbracoComponentRenderer _componentRenderer; + private IUmbracoComponentRenderer _componentRenderer; private PublishedContentQuery _query; private MembershipHelper _membershipHelper; private TagQuery _tag; @@ -223,7 +224,7 @@ namespace Umbraco.Web { if (query == null) throw new ArgumentNullException("query"); _query = query; - } + } #endregion /// @@ -232,7 +233,7 @@ namespace Umbraco.Web /// /// Note that this is the assigned IPublishedContent item to the UmbracoHelper, this is not necessarily the Current IPublishedContent item /// being rendered. This IPublishedContent object is contextual to the current UmbracoHelper instance. - /// + /// /// In some cases accessing this property will throw an exception if there is not IPublishedContent assigned to the Helper /// this will only ever happen if the Helper is constructed with an UmbracoContext and it is not a front-end request /// @@ -243,7 +244,7 @@ namespace Umbraco.Web { if (_currentPage == null) throw new InvalidOperationException("Cannot return the " + typeof(IPublishedContent).Name + " because the " + typeof(UmbracoHelper).Name + " was constructed with an " + typeof(UmbracoContext).Name + " and the current request is not a front-end request."); - + return _currentPage; } } @@ -315,15 +316,15 @@ namespace Umbraco.Web /// //// /// - public IHtmlString Field(string fieldAlias, + public IHtmlString Field(string fieldAlias, string altFieldAlias = "", string altText = "", string insertBefore = "", string insertAfter = "", bool recursive = false, bool convertLineBreaks = false, bool removeParagraphTags = false, RenderFieldCaseType casing = RenderFieldCaseType.Unchanged, - RenderFieldEncodingType encoding = RenderFieldEncodingType.Unchanged, - bool formatAsDate = false, + RenderFieldEncodingType encoding = RenderFieldEncodingType.Unchanged, + bool formatAsDate = false, bool formatAsDateWithTime = false, string formatAsDateWithTimeSeparator = "") - { + { return UmbracoComponentRenderer.Field(AssignedContentItem, fieldAlias, altFieldAlias, altText, insertBefore, insertAfter, recursive, convertLineBreaks, removeParagraphTags, casing, encoding, formatAsDate, formatAsDateWithTime, formatAsDateWithTimeSeparator); @@ -348,11 +349,11 @@ namespace Umbraco.Web /// //// /// - public IHtmlString Field(IPublishedContent currentPage, string fieldAlias, + public IHtmlString Field(IPublishedContent currentPage, string fieldAlias, string altFieldAlias = "", string altText = "", string insertBefore = "", string insertAfter = "", bool recursive = false, bool convertLineBreaks = false, bool removeParagraphTags = false, RenderFieldCaseType casing = RenderFieldCaseType.Unchanged, - RenderFieldEncodingType encoding = RenderFieldEncodingType.Unchanged, + RenderFieldEncodingType encoding = RenderFieldEncodingType.Unchanged, bool formatAsDate = false, bool formatAsDateWithTime = false, string formatAsDateWithTimeSeparator = "") @@ -424,7 +425,7 @@ namespace Umbraco.Web /// Check if the current user has access to a document /// /// The full path of the document object to check - /// True if the current user has access or if the current document isn't protected + /// True if the current user has access or if the current document isn't protected public bool MemberHasAccess(string path) { if (IsProtected(path)) @@ -455,7 +456,7 @@ namespace Umbraco.Web public bool MemberIsLoggedOn() { return MembershipHelper.IsLoggedIn(); - } + } #endregion @@ -495,7 +496,7 @@ namespace Umbraco.Web } /// - /// This method will always add the domain to the path if the hostnames are set up correctly. + /// This method will always add the domain to the path if the hostnames are set up correctly. /// /// Identifier for the node that should be returned /// String with a friendly url with full domain from a node @@ -560,53 +561,114 @@ namespace Umbraco.Web #region Content + /// + /// Gets a content item from the cache. + /// + /// The unique identifier, or the key, of the content item. + /// The content, or null of the content item is not in the cache. public IPublishedContent TypedContent(object id) - { - int intId; - return ConvertIdObjectToInt(id, out intId) ? ContentQuery.TypedContent(intId) : null; + { + return TypedContentForObject(id); } - public IPublishedContent TypedContent(int id) + private IPublishedContent TypedContentForObject(object id) + { + int intId; + if (ConvertIdObjectToInt(id, out intId)) + return ContentQuery.TypedContent(intId); + Guid guidId; + if (ConvertIdObjectToGuid(id, out guidId)) + return ContentQuery.TypedContent(guidId); + return null; + } + + /// + /// Gets a content item from the cache. + /// + /// The unique identifier of the content item. + /// The content, or null of the content item is not in the cache. + public IPublishedContent TypedContent(int id) { return ContentQuery.TypedContent(id); } + /// + /// Gets a content item from the cache. + /// + /// The key of the content item. + /// The content, or null of the content item is not in the cache. + public IPublishedContent TypedContent(Guid id) + { + return ContentQuery.TypedContent(id); + } + + /// + /// Gets a content item from the cache. + /// + /// The unique identifier, or the key, of the content item. + /// The content, or null of the content item is not in the cache. public IPublishedContent TypedContent(string id) { - int intId; - return ConvertIdObjectToInt(id, out intId) ? ContentQuery.TypedContent(intId) : null; - } + return TypedContentForObject(id); + } public IPublishedContent TypedContentSingleAtXPath(string xpath, params XPathVariable[] vars) { return ContentQuery.TypedContentSingleAtXPath(xpath, vars); } + /// + /// Gets content items from the cache. + /// + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public IEnumerable TypedContent(params object[] ids) { - return ContentQuery.TypedContent(ConvertIdsObjectToInts(ids)); + return TypedContentForObjects(ids); } + private IEnumerable TypedContentForObjects(IEnumerable ids) + { + var idsA = ids.ToArray(); + IEnumerable intIds; + if (ConvertIdsObjectToInts(idsA, out intIds)) + return ContentQuery.TypedContent(intIds); + IEnumerable guidIds; + if (ConvertIdsObjectToGuids(idsA, out guidIds)) + return ContentQuery.TypedContent(guidIds); + return Enumerable.Empty(); + } + /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers of the content items. + /// The content items that were found in the cache. public IEnumerable TypedContent(params int[] ids) { return ContentQuery.TypedContent(ids); } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The keys of the content items. + /// The content items that were found in the cache. + public IEnumerable TypedContent(params Guid[] ids) + { + return ContentQuery.TypedContent(ids); + } + + /// + /// Gets content items from the cache. + /// + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public IEnumerable TypedContent(params string[] ids) - { - return ContentQuery.TypedContent(ConvertIdsObjectToInts(ids)); + { + return TypedContentForObjects(ids); } /// @@ -616,8 +678,8 @@ namespace Umbraco.Web /// The existing contents corresponding to the identifiers. /// If an identifier does not match an existing content, it will be missing in the returned value. public IEnumerable TypedContent(IEnumerable ids) - { - return ContentQuery.TypedContent(ConvertIdsObjectToInts(ids)); + { + return TypedContentForObjects(ids); } /// @@ -628,7 +690,7 @@ namespace Umbraco.Web /// If an identifier does not match an existing content, it will be missing in the returned value. public IEnumerable TypedContent(IEnumerable ids) { - return ContentQuery.TypedContent(ConvertIdsObjectToInts(ids)); + return TypedContentForObjects(ids); } /// @@ -657,22 +719,46 @@ namespace Umbraco.Web return ContentQuery.TypedContentAtRoot(); } + /// + /// Gets a content item from the cache. + /// + /// The unique identifier, or the key, of the content item. + /// The content, or DynamicNull of the content item is not in the cache. public dynamic Content(object id) { - int intId; - return ConvertIdObjectToInt(id, out intId) ? ContentQuery.Content(intId) : DynamicNull.Null; + return ContentForObject(id); } - public dynamic Content(int id) + private dynamic ContentForObject(object id) + { + int intId; + if (ConvertIdObjectToInt(id, out intId)) + return ContentQuery.Content(intId); + Guid guidId; + if (ConvertIdObjectToGuid(id, out guidId)) + return ContentQuery.Content(guidId); + return DynamicNull.Null; + } + + /// + /// Gets a content item from the cache. + /// + /// The unique identifier of the content item. + /// The content, or DynamicNull of the content item is not in the cache. + public dynamic Content(int id) { return ContentQuery.Content(id); } + /// + /// Gets a content item from the cache. + /// + /// The unique identifier, or the key, of the content item. + /// The content, or DynamicNull of the content item is not in the cache. public dynamic Content(string id) { - int intId; - return ConvertIdObjectToInt(id, out intId) ? ContentQuery.Content(intId) : DynamicNull.Null; - } + return ContentForObject(id); + } public dynamic ContentSingleAtXPath(string xpath, params XPathVariable[] vars) { @@ -685,70 +771,80 @@ namespace Umbraco.Web } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public dynamic Content(params object[] ids) - { - return ContentQuery.Content(ConvertIdsObjectToInts(ids)); - } + { + return ContentForObjects(ids); + } + + private dynamic ContentForObjects(IEnumerable ids) + { + var idsA = ids.ToArray(); + IEnumerable intIds; + if (ConvertIdsObjectToInts(idsA, out intIds)) + return ContentQuery.Content(intIds); + IEnumerable guidIds; + if (ConvertIdsObjectToGuids(idsA, out guidIds)) + return ContentQuery.Content(guidIds); + return Enumerable.Empty(); + } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers of the content items. + /// The content items that were found in the cache. public dynamic Content(params int[] ids) { return ContentQuery.Content(ids); } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public dynamic Content(params string[] ids) { - return ContentQuery.Content(ConvertIdsObjectToInts(ids)); - } + return ContentForObjects(ids); + } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public dynamic Content(IEnumerable ids) { - return ContentQuery.Content(ConvertIdsObjectToInts(ids)); - } + return ContentForObjects(ids); + } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers of the content items. + /// The content items that were found in the cache. public dynamic Content(IEnumerable ids) { return ContentQuery.Content(ids); } /// - /// Gets the contents corresponding to the identifiers. + /// Gets content items from the cache. /// - /// The content identifiers. - /// The existing contents corresponding to the identifiers. - /// If an identifier does not match an existing content, it will be missing in the returned value. + /// The unique identifiers, or the keys, of the content items. + /// The content items that were found in the cache. + /// Does not support mixing identifiers and keys. public dynamic Content(IEnumerable ids) { - return ContentQuery.Content(ConvertIdsObjectToInts(ids)); - } + return ContentForObjects(ids); + } public dynamic ContentAtXPath(string xpath, params XPathVariable[] vars) { @@ -765,35 +861,68 @@ namespace Umbraco.Web return ContentQuery.ContentAtRoot(); } - private bool ConvertIdObjectToInt(object id, out int intId) + private static bool ConvertIdObjectToInt(object id, out int intId) { var s = id as string; if (s != null) { return int.TryParse(s, out intId); } - if (id is int) { intId = (int) id; return true; } - - throw new InvalidOperationException("The value of parameter 'id' must be either a string or an integer"); + intId = default(int); + return false; } - private IEnumerable ConvertIdsObjectToInts(IEnumerable ids) + private static bool ConvertIdObjectToGuid(object id, out Guid guidId) + { + var s = id as string; + if (s != null) + { + return Guid.TryParse(s, out guidId); + } + if (id is Guid) + { + guidId = (Guid) id; + return true; + } + guidId = default(Guid); + return false; + } + + private static bool ConvertIdsObjectToInts(IEnumerable ids, out IEnumerable intIds) { var list = new List(); + intIds = null; foreach (var id in ids) { int intId; if (ConvertIdObjectToInt(id, out intId)) - { list.Add(intId); - } + else + return false; // if one of them is not an int, fail } - return list; + intIds = list; + return true; + } + + private static bool ConvertIdsObjectToGuids(IEnumerable ids, out IEnumerable guidIds) + { + var list = new List(); + guidIds = null; + foreach (var id in ids) + { + Guid guidId; + if (ConvertIdObjectToGuid(id, out guidId)) + list.Add(guidId); + else + return false; // if one of them is not a guid, fail + } + guidIds = list; + return true; } #endregion @@ -806,7 +935,7 @@ namespace Umbraco.Web /// /// /// - /// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass + /// We accept an object type because GetPropertyValue now returns an 'object', we still want to allow people to pass /// this result in to this method. /// This method will throw an exception if the value is not of type int or string. /// @@ -834,9 +963,21 @@ namespace Umbraco.Web /// The existing medias corresponding to the identifiers. /// If an identifier does not match an existing media, it will be missing in the returned value. public IEnumerable TypedMedia(params object[] ids) - { - return ContentQuery.TypedMedia(ConvertIdsObjectToInts(ids)); - } + { + return TypedMediaForObjects(ids); + } + + private IEnumerable TypedMediaForObjects(IEnumerable ids) + { + var idsA = ids.ToArray(); + IEnumerable intIds; + if (ConvertIdsObjectToInts(idsA, out intIds)) + return ContentQuery.TypedMedia(intIds); + //IEnumerable guidIds; + //if (ConvertIdsObjectToGuids(idsA, out guidIds)) + // return ContentQuery.TypedMedia(guidIds); + return Enumerable.Empty(); + } /// /// Gets the medias corresponding to the identifiers. @@ -857,8 +998,8 @@ namespace Umbraco.Web /// If an identifier does not match an existing media, it will be missing in the returned value. public IEnumerable TypedMedia(params string[] ids) { - return ContentQuery.TypedMedia(ConvertIdsObjectToInts(ids)); - } + return TypedMediaForObjects(ids); + } /// /// Gets the medias corresponding to the identifiers. @@ -868,8 +1009,8 @@ namespace Umbraco.Web /// If an identifier does not match an existing media, it will be missing in the returned value. public IEnumerable TypedMedia(IEnumerable ids) { - return ContentQuery.TypedMedia(ConvertIdsObjectToInts(ids)); - } + return TypedMediaForObjects(ids); + } /// /// Gets the medias corresponding to the identifiers. @@ -890,8 +1031,8 @@ namespace Umbraco.Web /// If an identifier does not match an existing media, it will be missing in the returned value. public IEnumerable TypedMedia(IEnumerable ids) { - return ContentQuery.TypedMedia(ConvertIdsObjectToInts(ids)); - } + return TypedMediaForObjects(ids); + } public IEnumerable TypedMediaAtRoot() { @@ -922,9 +1063,21 @@ namespace Umbraco.Web /// The existing medias corresponding to the identifiers. /// If an identifier does not match an existing media, it will be missing in the returned value. public dynamic Media(params object[] ids) - { - return ContentQuery.Media(ConvertIdsObjectToInts(ids)); - } + { + return MediaForObjects(ids); + } + + private dynamic MediaForObjects(IEnumerable ids) + { + var idsA = ids.ToArray(); + IEnumerable intIds; + if (ConvertIdsObjectToInts(idsA, out intIds)) + return ContentQuery.Media(intIds); + //IEnumerable guidIds; + //if (ConvertIdsObjectToGuids(idsA, out guidIds)) + // return ContentQuery.Media(guidIds); + return Enumerable.Empty(); + } /// /// Gets the medias corresponding to the identifiers. @@ -944,8 +1097,8 @@ namespace Umbraco.Web /// The existing medias corresponding to the identifiers. /// If an identifier does not match an existing media, it will be missing in the returned value. public dynamic Media(params string[] ids) - { - return ContentQuery.Media(ConvertIdsObjectToInts(ids)); + { + return MediaForObjects(ids); } /// @@ -956,8 +1109,8 @@ namespace Umbraco.Web /// If an identifier does not match an existing media, it will be missing in the returned value. public dynamic Media(IEnumerable ids) { - return ContentQuery.Media(ConvertIdsObjectToInts(ids)); - } + return MediaForObjects(ids); + } /// /// Gets the medias corresponding to the identifiers. @@ -978,8 +1131,8 @@ namespace Umbraco.Web /// If an identifier does not match an existing media, it will be missing in the returned value. public dynamic Media(IEnumerable ids) { - return ContentQuery.Media(ConvertIdsObjectToInts(ids)); - } + return MediaForObjects(ids); + } public dynamic MediaAtRoot() { @@ -987,7 +1140,7 @@ namespace Umbraco.Web } #endregion - + #region Search /// @@ -1234,7 +1387,7 @@ namespace Umbraco.Web #endregion #region canvasdesigner - + [Obsolete("Use EnableCanvasDesigner on the HtmlHelper extensions instead")] public IHtmlString EnableCanvasDesigner() {