using Microsoft.Extensions.Logging; using System.Net; using System.Text.Json; using System.Text.RegularExpressions; namespace zero.Routing; public class Links : ILinks { protected IZeroStore Store { get; set; } protected ILogger Logger { get; set; } protected IEnumerable Providers { get; set; } public Links(IZeroStore store, ILogger logger, IEnumerable providers) { Store = store; Logger = logger; Providers = providers; } /// public T GetProvider() where T : class, ILinkProvider { Type type = typeof(T); return Providers.FirstOrDefault(x => x.GetType().IsAssignableFrom(type)) as T; } /// public async Task GetUrl(Link link) { ILinkProvider provider = Providers.LastOrDefault(x => x.CanProcess(link)); if (provider == null) { Logger.LogWarning("Could not find provider for link with area {area}", link.Area); return null; } return await provider.Resolve(link); } /// public async Task> GetUrls(params Link[] links) { Dictionary result = new(); foreach (Link link in links) { result.Add(link, await GetUrl(link)); } return result; } /// public ILinkProvider GetProvider(Link link) { return Providers.LastOrDefault(x => x.CanProcess(link)); } /// public async Task Parse(string html) { MatchCollection matches = Regex.Matches(html, "zero-link=\"(.+?)\"", RegexOptions.IgnoreCase); foreach (Match match in matches) { if (!match.Success) { continue; } string valueJson = WebUtility.HtmlDecode(match.Groups[1].Value); LinkFromRTE link = JsonSerializer.Deserialize(valueJson, new JsonSerializerOptions() { PropertyNameCaseInsensitive = true }); string url = await GetUrl(link.ToLink()); string href = url.HasValue() ? "href=\"" + url + "\"" : string.Empty; html = html.Replace(match.Value, href); } return html; } class LinkFromRTE { public string Area { get; set; } public string Suffix { get; set; } public Dictionary Values { get; set; } = new(); public Link ToLink() => new() { Area = Area, UrlSuffix = Suffix, Values = Values }; } } public interface ILinks { /// /// Get URL from a link object by finding a provider which can resolve the link /// Task GetUrl(Link link); /// /// Get URLs from link objects by finding matching providers /// Task> GetUrls(params Link[] links); /// /// Get the provider for a specific link /// ILinkProvider GetProvider(Link link); /// /// Find a provider by a specific type /// T GetProvider() where T : class, ILinkProvider; /// /// Parses HTML which comes from the rich-text-editor and converts link references. /// Task Parse(string html); }