Skip to content

Commit c60d8c8

Browse files
author
Paul Johnson
authored
Added EntityController.GetUrlsByIds support for int & guid + update MNTP (#11680)
Fixes issue with MNTP (for 8.18) in a partial view macro - GH #11631 Renamed GetUrlsByUdis to match, don't do this in v9 as it would be breaking there, instead mark it obsolete. TODO: v9 ensure integration test coverage, more painful here as no WebApplicationFactory.
1 parent 16fb4f4 commit c60d8c8

File tree

4 files changed

+130
-29
lines changed

4 files changed

+130
-29
lines changed

src/Umbraco.Web.UI.Client/src/common/mocks/resources/entity.mocks.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ angular.module('umbraco.mocks').
3434
return [200, nodes, null];
3535
}
3636

37-
function returnUrlsbyUdis(status, data, headers) {
37+
function returnUrlsByIds(status, data, headers) {
3838

3939
if (!mocksUtils.checkAuth()) {
4040
return [401, null, null];
@@ -83,8 +83,8 @@ angular.module('umbraco.mocks').
8383
.respond(returnEntitybyIdsPost);
8484

8585
$httpBackend
86-
.whenPOST(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetUrlsByUdis'))
87-
.respond(returnUrlsbyUdis);
86+
.whenPOST(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetUrlsByIds'))
87+
.respond(returnUrlsByIds);
8888

8989
$httpBackend
9090
.whenGET(mocksUtils.urlRegex('/umbraco/UmbracoApi/Entity/GetAncestors'))

src/Umbraco.Web.UI.Client/src/common/resources/entity.resource.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -127,19 +127,19 @@ function entityResource($q, $http, umbRequestHelper) {
127127
'Failed to retrieve url for id:' + id);
128128
},
129129

130-
getUrlsByUdis: function(udis, culture) {
131-
var query = "culture=" + (culture || "");
130+
getUrlsByIds: function(ids, type, culture) {
131+
var query = `type=${type}&culture=${culture || ""}`;
132132

133133
return umbRequestHelper.resourcePromise(
134134
$http.post(
135135
umbRequestHelper.getApiUrl(
136136
"entityApiBaseUrl",
137-
"GetUrlsByUdis",
137+
"GetUrlsByIds",
138138
query),
139139
{
140-
udis: udis
140+
ids: ids
141141
}),
142-
'Failed to retrieve url map for udis ' + udis);
142+
'Failed to retrieve url map for ids ' + ids);
143143
},
144144

145145
getUrlByUdi: function (udi, culture) {

src/Umbraco.Web.UI.Client/src/views/propertyeditors/contentpicker/contentpicker.controller.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ function contentPickerController($scope, $q, $routeParams, $location, entityReso
421421

422422
var requests = [
423423
entityResource.getByIds(missingIds, entityType),
424-
entityResource.getUrlsByUdis(missingIds)
424+
entityResource.getUrlsByIds(missingIds, entityType)
425425
];
426426

427427
return $q.all(requests).then(function ([data, urlMap]) {

src/Umbraco.Web/Editors/EntityController.cs

Lines changed: 121 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ public void Initialize(HttpControllerSettings controllerSettings, HttpController
7676
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetPath", "id", typeof(int), typeof(Guid), typeof(Udi)),
7777
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetUrlAndAnchors", "id", typeof(int), typeof(Guid), typeof(Udi)),
7878
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetById", "id", typeof(int), typeof(Guid), typeof(Udi)),
79-
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[]))));
79+
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[])),
80+
new ParameterSwapControllerActionSelector.ParameterSwapInfo("GetUrlsByIds", "ids", typeof(int[]), typeof(Guid[]), typeof(Udi[]))));
8081
}
8182
}
8283

@@ -236,47 +237,147 @@ public HttpResponseMessage GetUrl(Udi udi, string culture = "*")
236237
}
237238

238239
/// <summary>
239-
/// Get entity URLs by UDIs
240+
/// Get entity URLs by IDs
240241
/// </summary>
241-
/// <param name="udis">
242-
/// A list of UDIs to lookup items by
242+
/// <param name="ids">
243+
/// A list of IDs to lookup items by
243244
/// </param>
244-
/// <param name="culture">The culture to fetch the URL for</param>
245+
/// <param name="type">The entity type to look for.</param>
246+
/// <param name="culture">The culture to fetch the URL for.</param>
247+
/// <returns>Dictionary mapping Udi -> Url</returns>
248+
/// <remarks>
249+
/// We allow for POST because there could be quite a lot of Ids.
250+
/// </remarks>
251+
[HttpGet]
252+
[HttpPost]
253+
public IDictionary<int, string> GetUrlsByIds([FromJsonPath] int[] ids, [FromUri] UmbracoEntityTypes type, [FromUri] string culture = null)
254+
{
255+
if (ids == null || !ids.Any())
256+
{
257+
return new Dictionary<int, string>();
258+
}
259+
260+
string MediaOrDocumentUrl(int id)
261+
{
262+
switch (type)
263+
{
264+
case UmbracoEntityTypes.Document:
265+
return UmbracoContext.UrlProvider.GetUrl(id, culture: culture ?? ClientCulture());
266+
case UmbracoEntityTypes.Media: {
267+
var media = UmbracoContext.Media.GetById(id);
268+
// NOTE: If culture is passed here we get an empty string rather than a media item URL.
269+
return UmbracoContext.UrlProvider.GetMediaUrl(media, culture: null);
270+
}
271+
default:
272+
return null;
273+
}
274+
}
275+
276+
return ids
277+
.Distinct()
278+
.Select(id => new {
279+
Id = id,
280+
Url = MediaOrDocumentUrl(id)
281+
}).ToDictionary(x => x.Id, x => x.Url);
282+
}
283+
284+
/// <summary>
285+
/// Get entity URLs by IDs
286+
/// </summary>
287+
/// <param name="ids">
288+
/// A list of IDs to lookup items by
289+
/// </param>
290+
/// <param name="type">The entity type to look for.</param>
291+
/// <param name="culture">The culture to fetch the URL for.</param>
245292
/// <returns>Dictionary mapping Udi -> Url</returns>
246293
/// <remarks>
247294
/// We allow for POST because there could be quite a lot of Ids.
248295
/// </remarks>
249296
[HttpGet]
250297
[HttpPost]
251-
public IDictionary<Udi, string> GetUrlsByUdis([FromJsonPath] Udi[] udis, string culture = null)
298+
public IDictionary<Guid, string> GetUrlsByIds([FromJsonPath] Guid[] ids, [FromUri] UmbracoEntityTypes type, [FromUri] string culture = null)
252299
{
253-
if (udis == null || udis.Length == 0)
300+
if (ids == null || !ids.Any())
301+
{
302+
return new Dictionary<Guid, string>();
303+
}
304+
305+
string MediaOrDocumentUrl(Guid id)
306+
{
307+
switch (type)
308+
{
309+
case UmbracoEntityTypes.Document:
310+
return UmbracoContext.UrlProvider.GetUrl(id, culture: culture ?? ClientCulture());
311+
case UmbracoEntityTypes.Media:
312+
{
313+
var media = UmbracoContext.Media.GetById(id);
314+
// NOTE: If culture is passed here we get an empty string rather than a media item URL.
315+
return UmbracoContext.UrlProvider.GetMediaUrl(media, culture: null);
316+
}
317+
default:
318+
return null;
319+
}
320+
}
321+
322+
return ids
323+
.Distinct()
324+
.Select(id => new {
325+
Id = id,
326+
Url = MediaOrDocumentUrl(id)
327+
}).ToDictionary(x => x.Id, x => x.Url);
328+
}
329+
330+
/// <summary>
331+
/// Get entity URLs by IDs
332+
/// </summary>
333+
/// <param name="ids">
334+
/// A list of IDs to lookup items by
335+
/// </param>
336+
/// <param name="type">The entity type to look for.</param>
337+
/// <param name="culture">The culture to fetch the URL for.</param>
338+
/// <returns>Dictionary mapping Udi -> Url</returns>
339+
/// <remarks>
340+
/// We allow for POST because there could be quite a lot of Ids.
341+
/// </remarks>
342+
[HttpGet]
343+
[HttpPost]
344+
// NOTE: V9 - can't rename GetUrlsByUdis in v9 as it's already released, it's OK to do here as 8.18 isn't out yet.
345+
public IDictionary<Udi, string> GetUrlsByIds([FromJsonPath] Udi[] ids, [FromUri] UmbracoEntityTypes type, [FromUri] string culture = null)
346+
{
347+
if (ids == null || !ids.Any())
254348
{
255349
return new Dictionary<Udi, string>();
256350
}
257351

258352
// TODO: PMJ 2021-09-27 - Should GetUrl(Udi) exist as an extension method on UrlProvider/IUrlProvider (in v9)
259-
string MediaOrDocumentUrl(Udi udi)
353+
string MediaOrDocumentUrl(Udi id)
260354
{
261-
if (udi is not GuidUdi guidUdi)
355+
if (id is not GuidUdi guidUdi)
262356
{
263357
return null;
264358
}
265359

266-
return guidUdi.EntityType switch
360+
switch (type)
267361
{
268-
Constants.UdiEntityType.Document => UmbracoContext.UrlProvider.GetUrl(guidUdi.Guid, culture: culture ?? ClientCulture()),
269-
// NOTE: If culture is passed here we get an empty string rather than a media item URL WAT
270-
Constants.UdiEntityType.Media => UmbracoContext.UrlProvider.GetMediaUrl(guidUdi.Guid, culture: null),
271-
_ => null
272-
};
362+
case UmbracoEntityTypes.Document:
363+
return UmbracoContext.UrlProvider.GetUrl(guidUdi.Guid, culture: culture ?? ClientCulture());
364+
case UmbracoEntityTypes.Media:
365+
{
366+
var media = UmbracoContext.Media.GetById(id);
367+
// NOTE: If culture is passed here we get an empty string rather than a media item URL.
368+
return UmbracoContext.UrlProvider.GetMediaUrl(media, culture: null);
369+
}
370+
default:
371+
return null;
372+
}
273373
}
274374

275-
return udis
276-
.Select(udi => new {
277-
Udi = udi,
278-
Url = MediaOrDocumentUrl(udi)
279-
}).ToDictionary(x => x.Udi, x => x.Url);
375+
return ids
376+
.Distinct()
377+
.Select(id => new {
378+
Id = id,
379+
Url = MediaOrDocumentUrl(id)
380+
}).ToDictionary(x => x.Id, x => x.Url);
280381
}
281382

282383
/// <summary>

0 commit comments

Comments
 (0)