Skip to content

Commit fe5b17b

Browse files
authored
Merge pull request #86 from umbraco/feature/algolia-extend-indexing
Fix null reference bug & parsing of complex types
2 parents 8c39ffc + 0ebb5aa commit fe5b17b

13 files changed

+274
-72
lines changed

src/Umbraco.Cms.Integrations.Search.Algolia/AlgoliaComposer.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public void Compose(IUmbracoBuilder builder)
3434
builder.Services.AddSingleton<IAlgoliaSearchService<SearchResponse<Record>>, AlgoliaSearchService>();
3535

3636
builder.Services.AddScoped<IAlgoliaIndexDefinitionStorage<AlgoliaIndex>, AlgoliaIndexDefinitionStorage>();
37+
38+
builder.Services.AddScoped<IAlgoliaSearchPropertyIndexValueFactory, AlgoliaSearchPropertyIndexValueFactory>();
3739
}
3840

3941
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
using Umbraco.Cms.Core.Models;
2+
using Umbraco.Cms.Core.Models.PublishedContent;
3+
using Umbraco.Cms.Core.Routing;
4+
using Umbraco.Cms.Core.Services;
5+
using Umbraco.Cms.Integrations.Search.Algolia.Models;
6+
using Umbraco.Cms.Integrations.Search.Algolia.Services;
7+
8+
namespace Umbraco.Cms.Integrations.Search.Algolia.Builders
9+
{
10+
public class ContentRecordBuilder
11+
{
12+
private readonly Record _record = new();
13+
14+
private readonly IPublishedUrlProvider _urlProvider;
15+
16+
private readonly IAlgoliaSearchPropertyIndexValueFactory _algoliaSearchPropertyIndexValueFactory;
17+
18+
public ContentRecordBuilder(IPublishedUrlProvider urlProvider, IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
19+
{
20+
_urlProvider = urlProvider;
21+
22+
_algoliaSearchPropertyIndexValueFactory = algoliaSearchPropertyIndexValueFactory;
23+
}
24+
25+
public ContentRecordBuilder BuildFromContent(IContent content, Func<IProperty, bool> filter = null)
26+
{
27+
_record.ObjectID = content.Key.ToString();
28+
29+
_record.Id = content.Id;
30+
_record.Name = content.Name;
31+
_record.CreateDate = content.CreateDate.ToString();
32+
_record.UpdateDate = content.UpdateDate.ToString();
33+
_record.Url = _urlProvider.GetUrl(content.Id);
34+
35+
if (content.AvailableCultures.Count() > 0)
36+
{
37+
foreach (var culture in content.AvailableCultures)
38+
{
39+
_record.Data.Add($"name-{culture}", content.CultureInfos[culture].Name);
40+
_record.Data.Add($"url-{culture}", _urlProvider.GetUrl(content.Id, culture: culture));
41+
}
42+
}
43+
44+
foreach (var property in content.Properties.Where(filter ?? (p => true)))
45+
{
46+
if (!_record.Data.ContainsKey(property.Alias))
47+
{
48+
if (content.AvailableCultures.Count() > 0)
49+
{
50+
foreach (var culture in content.AvailableCultures)
51+
{
52+
var indexValue = _algoliaSearchPropertyIndexValueFactory.GetValue(property, culture);
53+
_record.Data.Add($"{indexValue.Key}-{culture}", indexValue.Value);
54+
}
55+
}
56+
else
57+
{
58+
var indexValue = _algoliaSearchPropertyIndexValueFactory.GetValue(property, string.Empty);
59+
_record.Data.Add(indexValue.Key, indexValue.Value);
60+
}
61+
62+
}
63+
}
64+
65+
return this;
66+
}
67+
68+
public Record Build() => _record;
69+
}
70+
}

src/Umbraco.Cms.Integrations.Search.Algolia/Builders/RecordBuilder.cs

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/Umbraco.Cms.Integrations.Search.Algolia/Controllers/SearchController.cs

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
using Microsoft.AspNetCore.Mvc;
44

55
using System.Text.Json;
6+
7+
using Umbraco.Cms.Core.Routing;
8+
using Umbraco.Cms.Core.Services;
9+
using Umbraco.Cms.Core.Services.Implement;
610
using Umbraco.Cms.Integrations.Search.Algolia.Builders;
711
using Umbraco.Cms.Integrations.Search.Algolia.Migrations;
812
using Umbraco.Cms.Integrations.Search.Algolia.Models;
@@ -25,9 +29,20 @@ public class SearchController : UmbracoAuthorizedApiController
2529

2630
private readonly UmbracoHelper _umbracoHelper;
2731

28-
public SearchController(IAlgoliaIndexService indexService, IAlgoliaSearchService<SearchResponse<Record>> searchService,
32+
private readonly IPublishedUrlProvider _urlProvider;
33+
34+
private readonly IContentService _contentService;
35+
36+
private readonly IAlgoliaSearchPropertyIndexValueFactory _algoliaSearchPropertyIndexValueFactory;
37+
38+
public SearchController(
39+
IAlgoliaIndexService indexService,
40+
IAlgoliaSearchService<SearchResponse<Record>> searchService,
2941
IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage,
30-
UmbracoHelper umbracoHelper)
42+
UmbracoHelper umbracoHelper,
43+
IPublishedUrlProvider urlProvider,
44+
IContentService contentService,
45+
IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
3146
{
3247
_indexService = indexService;
3348

@@ -36,11 +51,18 @@ public SearchController(IAlgoliaIndexService indexService, IAlgoliaSearchService
3651
_indexStorage = indexStorage;
3752

3853
_umbracoHelper = umbracoHelper;
54+
55+
_urlProvider = urlProvider;
56+
57+
_contentService = contentService;
58+
59+
_algoliaSearchPropertyIndexValueFactory = algoliaSearchPropertyIndexValueFactory;
3960
}
4061

4162
[HttpGet]
4263
public IActionResult GetIndices()
4364
{
65+
4466
var results = _indexStorage.Get().Select(p => new IndexConfiguration
4567
{
4668
Id = p.Id,
@@ -91,8 +113,8 @@ public async Task<IActionResult> BuildIndex([FromBody] IndexConfiguration indexC
91113

92114
foreach (var contentItem in contentItems)
93115
{
94-
var record = new RecordBuilder()
95-
.BuildFromContent(contentItem, (p) => contentDataItem.Properties.Any(q => q.Alias == p.Alias))
116+
var record = new ContentRecordBuilder(_urlProvider, _algoliaSearchPropertyIndexValueFactory)
117+
.BuildFromContent(_contentService.GetById(contentItem.Id), (p) => contentDataItem.Properties.Any(q => q.Alias == p.Alias))
96118
.Build();
97119

98120
payload.Add(record);

src/Umbraco.Cms.Integrations.Search.Algolia/Handlers/BaseContentHandler.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using Microsoft.Extensions.Logging;
2+
23
using System.Text.Json;
4+
35
using Umbraco.Cms.Core.Models;
4-
using Umbraco.Cms.Core.Notifications;
6+
using Umbraco.Cms.Core.Routing;
7+
using Umbraco.Cms.Core.Services;
58
using Umbraco.Cms.Integrations.Search.Algolia.Builders;
69
using Umbraco.Cms.Integrations.Search.Algolia.Migrations;
710
using Umbraco.Cms.Integrations.Search.Algolia.Models;
@@ -17,15 +20,25 @@ public abstract class BaseContentHandler
1720

1821
protected readonly IAlgoliaIndexService IndexService;
1922

23+
protected readonly IPublishedUrlProvider UrlProvider;
24+
25+
protected readonly IAlgoliaSearchPropertyIndexValueFactory AlgoliaSearchPropertyIndexValueFactory;
26+
2027
public BaseContentHandler(ILogger<BaseContentHandler> logger,
2128
IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage,
22-
IAlgoliaIndexService indexService)
29+
IAlgoliaIndexService indexService,
30+
IPublishedUrlProvider urlProvider,
31+
IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
2332
{
2433
Logger = logger;
2534

2635
IndexStorage = indexStorage;
2736

2837
IndexService = indexService;
38+
39+
UrlProvider = urlProvider;
40+
41+
AlgoliaSearchPropertyIndexValueFactory = algoliaSearchPropertyIndexValueFactory;
2942
}
3043

3144
protected async Task RebuildIndex(IEnumerable<IContent> entities, bool deleteIndexData = false)
@@ -42,7 +55,7 @@ protected async Task RebuildIndex(IEnumerable<IContent> entities, bool deleteInd
4255
.FirstOrDefault(p => p.ContentType.Alias == entity.ContentType.Alias);
4356
if (indexConfiguration == null || indexConfiguration.ContentType.Alias != entity.ContentType.Alias) continue;
4457

45-
var record = new RecordBuilder()
58+
var record = new ContentRecordBuilder(UrlProvider, AlgoliaSearchPropertyIndexValueFactory)
4659
.BuildFromContent(entity, (p) => indexConfiguration.Properties.Any(q => q.Alias == p.Alias))
4760
.Build();
4861

src/Umbraco.Cms.Integrations.Search.Algolia/Handlers/ContentDeletedHandler.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,23 @@
22

33
using Umbraco.Cms.Core.Events;
44
using Umbraco.Cms.Core.Notifications;
5+
using Umbraco.Cms.Core.Routing;
6+
using Umbraco.Cms.Core.Services;
57
using Umbraco.Cms.Integrations.Search.Algolia.Migrations;
68
using Umbraco.Cms.Integrations.Search.Algolia.Services;
9+
using Umbraco.Cms.Web.Common.UmbracoContext;
710

811
namespace Umbraco.Cms.Integrations.Search.Algolia.Handlers
912
{
1013
public class ContentDeletedHandler : BaseContentHandler, INotificationAsyncHandler<ContentDeletedNotification>
1114
{
12-
public ContentDeletedHandler(ILogger<ContentDeletedHandler> logger, IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage, IAlgoliaIndexService indexService)
13-
: base(logger, indexStorage, indexService)
15+
public ContentDeletedHandler(
16+
ILogger<ContentDeletedHandler> logger,
17+
IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage,
18+
IAlgoliaIndexService indexService,
19+
IPublishedUrlProvider urlProvider,
20+
IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
21+
: base(logger, indexStorage, indexService, urlProvider, algoliaSearchPropertyIndexValueFactory)
1422
{ }
1523

1624
public async Task HandleAsync(ContentDeletedNotification notification, CancellationToken cancellationToken) =>

src/Umbraco.Cms.Integrations.Search.Algolia/Handlers/ContentPublishedHandler.cs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,22 @@
22

33
using Umbraco.Cms.Core.Events;
44
using Umbraco.Cms.Core.Notifications;
5+
using Umbraco.Cms.Core.Routing;
6+
using Umbraco.Cms.Core.Services;
57
using Umbraco.Cms.Integrations.Search.Algolia.Migrations;
68
using Umbraco.Cms.Integrations.Search.Algolia.Services;
79

810
namespace Umbraco.Cms.Integrations.Search.Algolia.Handlers
911
{
1012
public class ContentPublishedHandler : BaseContentHandler, INotificationAsyncHandler<ContentPublishedNotification>
1113
{
12-
public ContentPublishedHandler(ILogger<ContentPublishedHandler> logger, IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage, IAlgoliaIndexService indexService)
13-
: base(logger, indexStorage, indexService)
14+
public ContentPublishedHandler(
15+
ILogger<ContentPublishedHandler> logger,
16+
IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage,
17+
IAlgoliaIndexService indexService,
18+
IPublishedUrlProvider urlProvider,
19+
IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
20+
: base(logger, indexStorage, indexService, urlProvider, algoliaSearchPropertyIndexValueFactory)
1421
{ }
1522

1623
public async Task HandleAsync(ContentPublishedNotification notification, CancellationToken cancellationToken) => await RebuildIndex(notification.PublishedEntities);

src/Umbraco.Cms.Integrations.Search.Algolia/Handlers/ContentUnpublishedHandler.cs

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
using Microsoft.Extensions.Logging;
22

3-
using System.Text.Json;
4-
53
using Umbraco.Cms.Core.Events;
64
using Umbraco.Cms.Core.Notifications;
5+
using Umbraco.Cms.Core.Routing;
6+
using Umbraco.Cms.Core.Services;
77
using Umbraco.Cms.Integrations.Search.Algolia.Migrations;
8-
using Umbraco.Cms.Integrations.Search.Algolia.Models;
98
using Umbraco.Cms.Integrations.Search.Algolia.Services;
109

1110
namespace Umbraco.Cms.Integrations.Search.Algolia.Handlers
1211
{
1312
public class ContentUnpublishedHandler : BaseContentHandler, INotificationAsyncHandler<ContentUnpublishedNotification>
1413
{
15-
public ContentUnpublishedHandler(ILogger<ContentUnpublishedHandler> logger, IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage, IAlgoliaIndexService indexService)
16-
: base(logger, indexStorage, indexService)
14+
public ContentUnpublishedHandler(
15+
ILogger<ContentUnpublishedHandler> logger,
16+
IAlgoliaIndexDefinitionStorage<AlgoliaIndex> indexStorage,
17+
IAlgoliaIndexService indexService,
18+
IPublishedUrlProvider urlProvider,
19+
IAlgoliaSearchPropertyIndexValueFactory algoliaSearchPropertyIndexValueFactory)
20+
: base(logger, indexStorage, indexService, urlProvider, algoliaSearchPropertyIndexValueFactory)
1721
{ }
1822

1923
public async Task HandleAsync(ContentUnpublishedNotification notification, CancellationToken cancellationToken) =>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace Umbraco.Cms.Integrations.Search.Algolia
4+
{
5+
public class MediaItem
6+
{
7+
[JsonPropertyName("key")]
8+
public string Key { get; set; } = string.Empty;
9+
10+
[JsonPropertyName("mediaKey")]
11+
public string MediaKey { get; set; } = string.Empty;
12+
}
13+
}

src/Umbraco.Cms.Integrations.Search.Algolia/Models/Record.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,16 @@ public Record()
1111

1212
public string ObjectID { get; set; }
1313

14+
public int Id { get; set; }
15+
16+
public string Name { get; set; }
17+
18+
public string CreateDate { get; set; }
19+
20+
public string UpdateDate { get; set; }
21+
22+
public string Url { get; set; }
23+
1424
public Dictionary<string, string> Data { get; set; }
1525
}
1626
}

0 commit comments

Comments
 (0)