breaking search modifications into smaller PRs
This commit is contained in:
parent
22063248ca
commit
0178e015e3
|
@ -95,19 +95,15 @@ namespace Oqtane.Managers.Search
|
||||||
searchContent.EntityName = EntityNames.Module;
|
searchContent.EntityName = EntityNames.Module;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(searchContent.EntityId == 0)
|
if(string.IsNullOrEmpty(searchContent.EntityId))
|
||||||
{
|
{
|
||||||
searchContent.EntityId = pageModule.ModuleId;
|
searchContent.EntityId = pageModule.ModuleId.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchContent.IsActive)
|
|
||||||
{
|
|
||||||
searchContent.IsActive = !pageModule.Module.IsDeleted;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (searchContent.ModifiedTime == DateTime.MinValue)
|
if (searchContent.ContentModifiedOn == DateTime.MinValue)
|
||||||
{
|
{
|
||||||
searchContent.ModifiedTime = pageModule.ModifiedOn;
|
searchContent.ContentModifiedOn = pageModule.ModifiedOn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(searchContent.AdditionalContent))
|
if (string.IsNullOrEmpty(searchContent.AdditionalContent))
|
||||||
|
|
|
@ -48,16 +48,18 @@ namespace Oqtane.Managers.Search
|
||||||
|
|
||||||
var searchContent = new SearchContent
|
var searchContent = new SearchContent
|
||||||
{
|
{
|
||||||
EntityName = EntityNames.Page,
|
|
||||||
EntityId = page.PageId,
|
|
||||||
SiteId = page.SiteId,
|
SiteId = page.SiteId,
|
||||||
ModifiedTime = page.ModifiedOn,
|
EntityName = EntityNames.Page,
|
||||||
AdditionalContent = string.Empty,
|
EntityId = page.PageId.ToString(),
|
||||||
Url = $"{(!string.IsNullOrEmpty(page.Path) && !page.Path.StartsWith("/") ? "/" : "")}{page.Path}",
|
|
||||||
Title = !string.IsNullOrEmpty(page.Title) ? page.Title : page.Name,
|
Title = !string.IsNullOrEmpty(page.Title) ? page.Title : page.Name,
|
||||||
Description = string.Empty,
|
Description = string.Empty,
|
||||||
Body = $"{page.Name} {page.Title}",
|
Body = $"{page.Name} {page.Title}",
|
||||||
IsActive = !page.IsDeleted && Utilities.IsPageModuleVisible(page.EffectiveDate, page.ExpiryDate)
|
Url = $"{(!string.IsNullOrEmpty(page.Path) && !page.Path.StartsWith("/") ? "/" : "")}{page.Path}",
|
||||||
|
Permissions = $"{EntityNames.Page}:{page.PageId}",
|
||||||
|
ContentModifiedBy = page.ModifiedBy,
|
||||||
|
ContentModifiedOn = page.ModifiedOn,
|
||||||
|
AdditionalContent = string.Empty,
|
||||||
|
CreatedOn = DateTime.UtcNow
|
||||||
};
|
};
|
||||||
|
|
||||||
if (searchContent.SearchContentProperties == null)
|
if (searchContent.SearchContentProperties == null)
|
||||||
|
|
|
@ -2,11 +2,10 @@ using Microsoft.EntityFrameworkCore.Migrations;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
using Microsoft.EntityFrameworkCore.Migrations.Operations;
|
||||||
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
using Microsoft.EntityFrameworkCore.Migrations.Operations.Builders;
|
||||||
using Oqtane.Databases.Interfaces;
|
using Oqtane.Databases.Interfaces;
|
||||||
using Oqtane.Models;
|
|
||||||
|
|
||||||
namespace Oqtane.Migrations.EntityBuilders
|
namespace Oqtane.Migrations.EntityBuilders
|
||||||
{
|
{
|
||||||
public class SearchContentEntityBuilder : AuditableBaseEntityBuilder<SearchContentEntityBuilder>
|
public class SearchContentEntityBuilder : BaseEntityBuilder<SearchContentEntityBuilder>
|
||||||
{
|
{
|
||||||
private const string _entityTableName = "SearchContent";
|
private const string _entityTableName = "SearchContent";
|
||||||
private readonly PrimaryKey<SearchContentEntityBuilder> _primaryKey = new("PK_SearchContent", x => x.SearchContentId);
|
private readonly PrimaryKey<SearchContentEntityBuilder> _primaryKey = new("PK_SearchContent", x => x.SearchContentId);
|
||||||
|
@ -20,30 +19,30 @@ namespace Oqtane.Migrations.EntityBuilders
|
||||||
protected override SearchContentEntityBuilder BuildTable(ColumnsBuilder table)
|
protected override SearchContentEntityBuilder BuildTable(ColumnsBuilder table)
|
||||||
{
|
{
|
||||||
SearchContentId = AddAutoIncrementColumn(table, "SearchContentId");
|
SearchContentId = AddAutoIncrementColumn(table, "SearchContentId");
|
||||||
|
SiteId = AddIntegerColumn(table, "SiteId");
|
||||||
EntityName = AddStringColumn(table, "EntityName", 50);
|
EntityName = AddStringColumn(table, "EntityName", 50);
|
||||||
EntityId = AddIntegerColumn(table, "EntityId");
|
EntityId = AddIntegerColumn(table, "EntityId");
|
||||||
SiteId = AddIntegerColumn(table, "SiteId");
|
Title = AddStringColumn(table, "Title", 200);
|
||||||
Title = AddStringColumn(table, "Title", 255);
|
|
||||||
Description = AddMaxStringColumn(table, "Description");
|
Description = AddMaxStringColumn(table, "Description");
|
||||||
Body = AddMaxStringColumn(table, "Body");
|
Body = AddMaxStringColumn(table, "Body");
|
||||||
Url = AddStringColumn(table, "Url", 255);
|
Url = AddStringColumn(table, "Url", 500);
|
||||||
ModifiedTime = AddDateTimeColumn(table, "ModifiedTime");
|
Permissions = AddStringColumn(table, "Permissions", 100);
|
||||||
IsActive = AddBooleanColumn(table, "IsActive");
|
ContentModifiedBy = AddStringColumn(table, "ContentModifiedBy", 256);
|
||||||
|
ContentModifiedOn = AddDateTimeColumn(table, "ContentModifiedOn");
|
||||||
AdditionalContent = AddMaxStringColumn(table, "AdditionalContent");
|
AdditionalContent = AddMaxStringColumn(table, "AdditionalContent");
|
||||||
|
CreatedOn = AddDateTimeColumn(table, "CreatedOn");
|
||||||
AddAuditableColumns(table);
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> SearchContentId { get; private set; }
|
public OperationBuilder<AddColumnOperation> SearchContentId { get; private set; }
|
||||||
|
|
||||||
|
public OperationBuilder<AddColumnOperation> SiteId { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> EntityName { get; private set; }
|
public OperationBuilder<AddColumnOperation> EntityName { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> EntityId { get; private set; }
|
public OperationBuilder<AddColumnOperation> EntityId { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> SiteId { get; private set; }
|
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> Title { get; private set; }
|
public OperationBuilder<AddColumnOperation> Title { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> Description { get; private set; }
|
public OperationBuilder<AddColumnOperation> Description { get; private set; }
|
||||||
|
@ -52,10 +51,14 @@ namespace Oqtane.Migrations.EntityBuilders
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> Url { get; private set; }
|
public OperationBuilder<AddColumnOperation> Url { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> ModifiedTime { get; private set; }
|
public OperationBuilder<AddColumnOperation> Permissions { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> IsActive { get; private set; }
|
public OperationBuilder<AddColumnOperation> ContentModifiedBy { get; private set; }
|
||||||
|
|
||||||
|
public OperationBuilder<AddColumnOperation> ContentModifiedOn { get; private set; }
|
||||||
|
|
||||||
public OperationBuilder<AddColumnOperation> AdditionalContent { get; private set; }
|
public OperationBuilder<AddColumnOperation> AdditionalContent { get; private set; }
|
||||||
|
|
||||||
|
public OperationBuilder<AddColumnOperation> CreatedOn { get; private set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,7 +62,8 @@ namespace Oqtane.Modules.HtmlText.Manager
|
||||||
Title = module.Title,
|
Title = module.Title,
|
||||||
Description = string.Empty,
|
Description = string.Empty,
|
||||||
Body = htmltext.Content,
|
Body = htmltext.Content,
|
||||||
ModifiedTime = htmltext.ModifiedOn
|
ContentModifiedBy = htmltext.ModifiedBy,
|
||||||
|
ContentModifiedOn = htmltext.ModifiedOn
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,13 +74,13 @@ namespace Oqtane.Providers
|
||||||
switch (searchQuery.SortField)
|
switch (searchQuery.SortField)
|
||||||
{
|
{
|
||||||
case SearchSortFields.Relevance:
|
case SearchSortFields.Relevance:
|
||||||
results = results.OrderByDescending(i => i.Score).ThenByDescending(i => i.ModifiedTime);
|
results = results.OrderByDescending(i => i.Score).ThenByDescending(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
case SearchSortFields.Title:
|
case SearchSortFields.Title:
|
||||||
results = results.OrderByDescending(i => i.Title).ThenByDescending(i => i.ModifiedTime);
|
results = results.OrderByDescending(i => i.Title).ThenByDescending(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
results = results.OrderByDescending(i => i.ModifiedTime);
|
results = results.OrderByDescending(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,13 +89,13 @@ namespace Oqtane.Providers
|
||||||
switch (searchQuery.SortField)
|
switch (searchQuery.SortField)
|
||||||
{
|
{
|
||||||
case SearchSortFields.Relevance:
|
case SearchSortFields.Relevance:
|
||||||
results = results.OrderBy(i => i.Score).ThenByDescending(i => i.ModifiedTime);
|
results = results.OrderBy(i => i.Score).ThenByDescending(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
case SearchSortFields.Title:
|
case SearchSortFields.Title:
|
||||||
results = results.OrderBy(i => i.Title).ThenByDescending(i => i.ModifiedTime);
|
results = results.OrderBy(i => i.Title).ThenByDescending(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
results = results.OrderBy(i => i.ModifiedTime);
|
results = results.OrderBy(i => i.ContentModifiedOn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -135,7 +135,9 @@ namespace Oqtane.Providers
|
||||||
Description = searchContent.Description,
|
Description = searchContent.Description,
|
||||||
Body = searchContent.Body,
|
Body = searchContent.Body,
|
||||||
Url = searchContent.Url,
|
Url = searchContent.Url,
|
||||||
ModifiedTime = searchContent.ModifiedTime,
|
Permissions = searchContent.Permissions,
|
||||||
|
ContentModifiedBy = searchContent.ContentModifiedBy,
|
||||||
|
ContentModifiedOn = searchContent.ContentModifiedOn,
|
||||||
SearchContentProperties = searchContent.SearchContentProperties,
|
SearchContentProperties = searchContent.SearchContentProperties,
|
||||||
Snippet = BuildSnippet(searchContent, searchQuery),
|
Snippet = BuildSnippet(searchContent, searchQuery),
|
||||||
Score = CalculateScore(searchContent, searchQuery)
|
Score = CalculateScore(searchContent, searchQuery)
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace Oqtane.Repository
|
||||||
Task<IEnumerable<SearchContent>> GetSearchContentsAsync(SearchQuery searchQuery);
|
Task<IEnumerable<SearchContent>> GetSearchContentsAsync(SearchQuery searchQuery);
|
||||||
SearchContent AddSearchContent(SearchContent searchContent);
|
SearchContent AddSearchContent(SearchContent searchContent);
|
||||||
void DeleteSearchContent(int searchContentId);
|
void DeleteSearchContent(int searchContentId);
|
||||||
void DeleteSearchContent(string entityName, int entryId);
|
void DeleteSearchContent(string entityName, string entryId);
|
||||||
void DeleteSearchContent(string uniqueKey);
|
void DeleteSearchContent(string uniqueKey);
|
||||||
void DeleteAllSearchContent();
|
void DeleteAllSearchContent();
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace Oqtane.Repository
|
||||||
.Include(i => i.SearchContentProperties)
|
.Include(i => i.SearchContentProperties)
|
||||||
.Include(i => i.SearchContentWords)
|
.Include(i => i.SearchContentWords)
|
||||||
.ThenInclude(w => w.SearchWord)
|
.ThenInclude(w => w.SearchWord)
|
||||||
.Where(i => i.SiteId == searchQuery.SiteId && i.IsActive);
|
.Where(i => i.SiteId == searchQuery.SiteId);
|
||||||
|
|
||||||
if (searchQuery.EntityNames != null && searchQuery.EntityNames.Any())
|
if (searchQuery.EntityNames != null && searchQuery.EntityNames.Any())
|
||||||
{
|
{
|
||||||
|
@ -33,12 +33,12 @@ namespace Oqtane.Repository
|
||||||
|
|
||||||
if (searchQuery.BeginModifiedTimeUtc != DateTime.MinValue)
|
if (searchQuery.BeginModifiedTimeUtc != DateTime.MinValue)
|
||||||
{
|
{
|
||||||
searchContents = searchContents.Where(i => i.ModifiedTime >= searchQuery.BeginModifiedTimeUtc);
|
searchContents = searchContents.Where(i => i.ContentModifiedOn >= searchQuery.BeginModifiedTimeUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.EndModifiedTimeUtc != DateTime.MinValue)
|
if (searchQuery.EndModifiedTimeUtc != DateTime.MinValue)
|
||||||
{
|
{
|
||||||
searchContents = searchContents.Where(i => i.ModifiedTime <= searchQuery.EndModifiedTimeUtc);
|
searchContents = searchContents.Where(i => i.ContentModifiedOn <= searchQuery.EndModifiedTimeUtc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (searchQuery.Properties != null && searchQuery.Properties.Any())
|
if (searchQuery.Properties != null && searchQuery.Properties.Any())
|
||||||
|
@ -88,7 +88,7 @@ namespace Oqtane.Repository
|
||||||
db.SaveChanges();
|
db.SaveChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void DeleteSearchContent(string entityName, int entryId)
|
public void DeleteSearchContent(string entityName, string entryId)
|
||||||
{
|
{
|
||||||
using var db = _dbContextFactory.CreateDbContext();
|
using var db = _dbContextFactory.CreateDbContext();
|
||||||
var searchContent = db.SearchContent.FirstOrDefault(i => i.EntityName == entityName && i.EntityId == entryId);
|
var searchContent = db.SearchContent.FirstOrDefault(i => i.EntityName == entityName && i.EntityId == entryId);
|
||||||
|
|
|
@ -10,6 +10,7 @@ using Oqtane.Models;
|
||||||
using Oqtane.Repository;
|
using Oqtane.Repository;
|
||||||
using Oqtane.Security;
|
using Oqtane.Security;
|
||||||
using Oqtane.Shared;
|
using Oqtane.Shared;
|
||||||
|
using SixLabors.ImageSharp.Metadata.Profiles.Exif;
|
||||||
|
|
||||||
namespace Oqtane.Services
|
namespace Oqtane.Services
|
||||||
{
|
{
|
||||||
|
@ -199,17 +200,18 @@ namespace Oqtane.Services
|
||||||
|
|
||||||
private bool Visible(SearchContent searchContent, SearchQuery searchQuery)
|
private bool Visible(SearchContent searchContent, SearchQuery searchQuery)
|
||||||
{
|
{
|
||||||
if(!HasViewPermission(searchQuery.SiteId, searchQuery.User, searchContent.EntityName, searchContent.EntityId))
|
var visible = true;
|
||||||
|
foreach (var permission in searchContent.Permissions.Split(','))
|
||||||
{
|
{
|
||||||
return false;
|
var entityName = permission.Split(":")[0];
|
||||||
}
|
var entityId = int.Parse(permission.Split(":")[1]);
|
||||||
|
if (!HasViewPermission(searchQuery.SiteId, searchQuery.User, entityName, entityId))
|
||||||
var searchResultManager = GetSearchResultManagers().FirstOrDefault(i => i.Name == searchContent.EntityName);
|
|
||||||
if (searchResultManager != null)
|
|
||||||
{
|
{
|
||||||
return searchResultManager.Visible(searchContent, searchQuery);
|
visible = false;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return true;
|
}
|
||||||
|
return visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool HasViewPermission(int siteId, User user, string entityName, int entityId)
|
private bool HasViewPermission(int siteId, User user, string entityName, int entityId)
|
||||||
|
|
|
@ -4,18 +4,15 @@ using System.ComponentModel.DataAnnotations.Schema;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
namespace Oqtane.Models
|
namespace Oqtane.Models
|
||||||
{
|
{
|
||||||
public class SearchContent : ModelBase
|
public class SearchContent
|
||||||
{
|
{
|
||||||
public int SearchContentId { get; set; }
|
public int SearchContentId { get; set; }
|
||||||
|
|
||||||
[NotMapped]
|
public int SiteId { get; set; }
|
||||||
public string UniqueKey => $"{EntityName}:{EntityId}";
|
|
||||||
|
|
||||||
public string EntityName { get; set; }
|
public string EntityName { get; set; }
|
||||||
|
|
||||||
public int EntityId { get; set; }
|
public string EntityId { get; set; }
|
||||||
|
|
||||||
public int SiteId { get; set; }
|
|
||||||
|
|
||||||
public string Title { get; set; }
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
@ -25,16 +22,45 @@ namespace Oqtane.Models
|
||||||
|
|
||||||
public string Url { get; set; }
|
public string Url { get; set; }
|
||||||
|
|
||||||
public DateTime ModifiedTime { get; set; }
|
public string Permissions { get; set; }
|
||||||
|
|
||||||
public bool IsActive { get; set; } = true;
|
public string ContentModifiedBy { get; set; }
|
||||||
|
|
||||||
|
public DateTime ContentModifiedOn { get; set; }
|
||||||
|
|
||||||
public string AdditionalContent { get; set; }
|
public string AdditionalContent { get; set; }
|
||||||
|
|
||||||
|
public DateTime CreatedOn { get; set; }
|
||||||
|
|
||||||
public List<SearchContentProperty> SearchContentProperties { get; set; }
|
public List<SearchContentProperty> SearchContentProperties { get; set; }
|
||||||
|
|
||||||
public List<SearchContentWord> SearchContentWords { get; set; }
|
public List<SearchContentWord> SearchContentWords { get; set; }
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public string UniqueKey => $"{EntityName}:{EntityId}";
|
||||||
|
|
||||||
|
[NotMapped]
|
||||||
|
public int TenantId { get; set; }
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
public SearchContent() { }
|
||||||
|
|
||||||
|
public SearchContent(int siteId, string entityName, string entityId, string title, string description, string body, string url, string permissions, string contentModifiedBy, DateTime contentModifiedOn)
|
||||||
|
{
|
||||||
|
SiteId = siteId;
|
||||||
|
EntityName = entityName;
|
||||||
|
EntityId = entityId;
|
||||||
|
Title = title;
|
||||||
|
Description = description;
|
||||||
|
Body = body;
|
||||||
|
Url = url;
|
||||||
|
Permissions = permissions;
|
||||||
|
ContentModifiedBy = contentModifiedBy;
|
||||||
|
ContentModifiedOn = contentModifiedOn;
|
||||||
|
AdditionalContent = "";
|
||||||
|
CreatedOn = DateTime.UtcNow;
|
||||||
|
}
|
||||||
|
|
||||||
public override string ToString()
|
public override string ToString()
|
||||||
{
|
{
|
||||||
return JsonSerializer.Serialize(this);
|
return JsonSerializer.Serialize(this);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user