Skip to content

Instantly share code, notes, and snippets.

@OwainWilliams
Last active December 23, 2021 14:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OwainWilliams/abd72f6f6f58db9f0ef484ea810162fc to your computer and use it in GitHub Desktop.
Save OwainWilliams/abd72f6f6f58db9f0ef484ea810162fc to your computer and use it in GitHub Desktop.
Migrating Code from Umbraco 8 to 9
using Examine;
using Examine.Search;
using Microsoft.Extensions.DependencyInjection;
using owaincodes.Interfaces;
using owaincodes.Models;
using Serilog;
using System;
using System.Collections.Generic;
using System.Linq;
using Umbraco.Cms.Core.Composing;
using Umbraco.Cms.Core.DependencyInjection;
using Umbraco.Cms.Core.Models.PublishedContent;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Web;
using Umbraco.Cms.Web.Common;
using Umbraco.Cms.Web.Common.PublishedModels;
using Umbraco.Extensions;
namespace owaincodes.Services
{
public class BlogSearchService
{
private readonly ILogger logger;
private readonly UmbracoHelper umbracoHelper;
private readonly ISearcher searcher;
private readonly IExamineManager _examineManager;
private readonly IScopeProvider scopeProvider;
private readonly IUmbracoContextFactory umbracoContextFactory;
//private readonly UmbracoWebService umbracoWebService;
public BlogSearchService(IExamineManager examineManager)
{
_examineManager = examineManager ?? throw new ArgumentException(nameof(examineManager));
}
public PagedResults<BlogPage> GetPagedBlogFeed(PaginationDetails pageFilterModel)
{
try
{
if (!_examineManager.TryGetIndex(Umbraco.Cms.Core.Constants.UmbracoIndexes.ExternalIndexName, out var index))
{
throw new InvalidOperationException($"No index found by name {Umbraco.Cms.Core.Constants.UmbracoIndexes.ExternalIndexName}");
}
var searcher = index.Searcher;
if (pageFilterModel is null)
{
throw new ArgumentException(nameof(pageFilterModel));
}
if (pageFilterModel.CurrentPage < 1) pageFilterModel.CurrentPage = 1;
if (pageFilterModel.PageSize < 1) pageFilterModel.PageSize = 1;
var currentPageId = pageFilterModel.CurrentPageId;
var siteRoot = umbracoHelper.Content(currentPageId).Root().Id;
ISearchResults results = SearchForBlogs(searcher, siteRoot);
return ProcessSearchResults<BlogPage>((int)pageFilterModel.CurrentPage, (int)pageFilterModel.PageSize, results);
}
catch (Exception ex)
{
logger.Error(ex, "Error getting Posts - {{page}", pageFilterModel.CurrentPage);
}
return new PagedResults<BlogPage>(-1, -1, -1)
{
Results = Enumerable.Empty<BlogPage>()
};
}
private PagedResults<T> ProcessSearchResults<T>(int page, int pageSize, ISearchResults results) where T : IPublishedContent
{
if (page * pageSize > results.TotalItemCount)
{
page = CalculateFinalPage(pageSize, results.TotalItemCount);
}
var pageResults = page > 1 ?
results.Skip((page - 1) * pageSize).Take(pageSize) : results.Take(pageSize);
//var pageResults = results.TotalItemCount > 0 ? results.Skip((page - 1) * pageSize).Take(pageSize) : Enumerable.Empty<ISearchResult>();
var returnModel = new PagedResults<T>(page, pageSize, Convert.ToInt32(results.TotalItemCount));
using (var scope = scopeProvider.CreateScope())
{
using (var umbracoContext = umbracoContextFactory.EnsureUmbracoContext())
{
returnModel.Results = results.Count() > 0 ? pageResults.Select(r => umbracoContext.UmbracoContext.Content.GetById(int.Parse(r.Id)))
.OfType<T>().ToList()
: Enumerable.Empty<T>();
scope.Complete();
return returnModel;
}
}
}
private int CalculateFinalPage(int pageSize, long totalItemCount)
{
return Convert.ToInt32(Math.Ceiling(totalItemCount / Convert.ToDecimal(pageSize)));
}
public IEnumerable<BlogPage> GetOlderBlogPages(int qty, int skip)
{
var currentPage = umbracoHelper.AssignedContentItem.Id;
var rootId = umbracoHelper.Content(currentPage).Root().Id;
try
{
// return this.umbracoHelper.Content(this.searcher.CreateQuery().NodeTypeAlias("blogPage").OrderByDescending(new SortableField("sortOrder", SortType.Int)).Execute().Take<ISearchResult>(qty).Select<ISearchResult, string>((Func<ISearchResult, string>)(r => r.Id))).OfType<BlogPage>();
return this.umbracoHelper.Content(this.searcher.CreateQuery()
.NodeTypeAlias("blogPage")
.And().Field("FriendlyPath", "" + rootId + "")
.OrderByDescending(new SortableField(Constants.Blogs.BlogDateSortableExamineField, SortType.Long))
.Execute()
.Skip<ISearchResult>(skip)
.Take<ISearchResult>(qty)
.Select<ISearchResult, string>((Func<ISearchResult, string>)(r => r.Id)))
.OfType<BlogPage>().ToList();
}
catch (Exception ex)
{
this.logger.Error(ex, "Error getting latest blogs");
}
return (IEnumerable<BlogPage>)new List<BlogPage>();
}
private ISearchResults SearchForBlogs(ISearcher searcher, int rootId)
{
var query = searcher.CreateQuery().NodeTypeAlias(BlogPage.ModelTypeAlias);
query = query.And().RangeQuery<long>(new[] { Constants.Blogs.BlogDateSortableExamineField }, 0, DateTime.Now.Ticks, maxInclusive: true);
query = query.And().Field("FriendlyPath", "" + rootId + "");
var results = query.OrderByDescending(new SortableField(Constants.Blogs.BlogDateSortableExamineField, SortType.Long))
.Execute();
return results;
}
private IEnumerable<T> ProcessRssResults<T>(ISearchResults results) where T : IPublishedContent
{
using (var scope = scopeProvider.CreateScope())
{
using (var umbracoContext = umbracoContextFactory.EnsureUmbracoContext())
{
IEnumerable<T> resultOfRss = results.Any() ? results.Select(r => umbracoContext.UmbracoContext.Content.GetById(int.Parse(r.Id)))
.OfType<T>().ToList()
: Enumerable.Empty<T>();
scope.Complete();
return resultOfRss;
}
}
}
public IEnumerable<BlogPage> GetAllBlogs()
{
var currentPage = umbracoHelper.AssignedContentItem.Id;
var siteRoot = umbracoHelper.Content(currentPage).Root().Id;
ISearchResults blogSearchResults = SearchForBlogs(searcher, siteRoot);
IEnumerable<BlogPage> rssResults = ProcessRssResults<BlogPage>(blogSearchResults);
return rssResults;
}
}
}

HomepageBlogListing.cshtml

  @await Component.InvokeAsync("HomepageBlog", new { PageSize=5, CurrentPageId = currentPage }) 

HomepageBlogViewComponent.cs

  public class HomepageBlogViewComponent : ViewComponent
   {
       private IBlogSearchService blogSearchService;

       public HomepageBlogViewComponent(IBlogSearchService blogSearchService)
       {
           this.blogSearchService = blogSearchService ?? throw new ArgumentException(nameof(blogSearchService));
       }
       public IViewComponentResult Invoke(PaginationDetails model)
       {
           var returnModel = blogSearchService.GetPagedBlogFeed(model);

           return View();
       }

   }

IBlogSearchService.cs


namespace owaincodes.Interfaces
{
    public interface IBlogSearchService
    {
        PagedResults<BlogPage> GetPagedBlogFeed(PaginationDetails pageFilterModel);

        IEnumerable<BlogPage> GetOlderBlogPages(int qty, int skip);

        IEnumerable<BlogPage> GetAllBlogs();
    }
}

RegisterBlogServiceComposer.cs

 public class RegisterBlogServiceComposer : IComposer
    {
        public void Compose(IUmbracoBuilder builder)
        {
            var services = builder.Services;
             services.AddTransient<IBlogSearchService, BlogSearchService>();
        }
    }

Error: InvalidOperationException: Unable to resolve service for type 'owaincodes.Interfaces.IBlogSearchService' while attempting to activate 'OwainCodes.Core.HomepageBlogViewComponent'.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment