Skip to content

Instantly share code, notes, and snippets.

@ceee
Last active July 13, 2017 09:24
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 ceee/3a4053b16f61850baa987a8888e456e6 to your computer and use it in GitHub Desktop.
Save ceee/3a4053b16f61850baa987a8888e456e6 to your computer and use it in GitHub Desktop.
Fixed FormRecordSearcher (Umbraco.Forms) so used methods are public
using System;
using Umbraco.Core;
using Umbraco.Forms.Core;
using Umbraco.Forms.Web.BusinessLogic;
using Umbraco.Forms.Web.Models.Backoffice;
namespace MyNamespace
{
public class CustomExportType : ExportType
{
public CustomExportType()
{
Name = "...";
Description = "...";
Id = new Guid("...");
FileExtension = "xml";
Icon = "icon-file";
}
public override string ExportRecords(RecordExportFilter filter)
{
EntrySearchResultCollection model = FormRecordSearcherPublic.QueryDataBase(filter, ApplicationContext.Current.DatabaseContext);
return "...";
}
}
}
using Examine;
using Examine.LuceneEngine.SearchCriteria;
using Examine.Providers;
using Examine.SearchCriteria;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
using Umbraco.Forms.Core;
using Umbraco.Forms.Core.Enums;
using Umbraco.Forms.Data.Storage;
using Umbraco.Forms.Web.Models.Backoffice;
namespace Umbraco.Forms.Web.BusinessLogic
{
public class FormRecordSearcherPublic
{
internal static ISearchCriteria BuildLuceneQuery(RecordFilter model, BaseSearchProvider searcher)
{
if (model.StartIndex == 0)
{
model.StartIndex = 0;
}
if (model.Length == 0)
{
model.Length = 50;
}
DateTime startDate = model.StartDate;
DateTime now = new DateTime();
if (startDate == now)
{
now = DateTime.Now;
model.StartDate = now.Subtract(TimeSpan.FromDays(2));
}
DateTime endDate = model.EndDate;
now = new DateTime();
if (endDate == now)
{
model.EndDate = DateTime.Now;
}
if (model.States == null)
{
model.States = new List<FormState>()
{
FormState.Approved,
FormState.Submitted
};
}
IBooleanOperation booleanOperation = searcher.CreateSearchCriteria().Field("__IndexType", "formrecord").And().Range("Created", model.StartDate, model.EndDate);
if (model.Form != Guid.Empty)
{
IQuery query = booleanOperation.And();
Guid form = model.Form;
booleanOperation = query.Field("Form", form.ToString());
}
if (!string.IsNullOrEmpty(model.Filter))
{
booleanOperation = booleanOperation.And().Field("Blob", LuceneSearchExtensions.MultipleCharacterWildcard(model.Filter));
}
return booleanOperation.Compile();
}
internal static Sql BuildSqlQuery(RecordFilter model, string select = "")
{
object[] startDate;
if (model.StartIndex == 0)
{
model.StartIndex = 0;
}
if (model.Length == 0)
{
model.Length = 50;
}
DateTime dateTime = model.StartDate;
DateTime now = new DateTime();
if (dateTime == now)
{
now = DateTime.Now;
model.StartDate = now.Subtract(TimeSpan.FromDays(2000));
}
DateTime endDate = model.EndDate;
now = new DateTime();
if (endDate == now)
{
model.EndDate = DateTime.Now;
}
if (model.States == null)
{
model.States = new List<FormState>()
{
FormState.Approved,
FormState.Submitted
};
}
Sql sql = new Sql();
if (!string.IsNullOrEmpty(select))
{
startDate = new object[] { select };
sql = sql.Select(startDate);
}
sql = PetaPocoSqlExtensions.From<Record>(sql);
startDate = new object[] { model.StartDate, null };
now = model.EndDate;
startDate[1] = now.AddDays(1);
sql.Where("Created >= @0 AND Created <= @1", startDate);
if (model.Form != Guid.Empty)
{
startDate = new object[] { model.Form.ToString() };
sql = sql.Where("Form = @0", startDate);
}
if (!string.IsNullOrEmpty(model.Filter))
{
startDate = new object[] { string.Concat("%", model.Filter, "%") };
sql = sql.Where("RecordData LIKE @0", startDate);
}
if (model.States.Any<FormState>())
{
Sql sql1 = sql;
startDate = new object[] { new { states = (
from state in model.States
select state.ToString()).ToList<string>() } };
sql = sql1.Where("State in (@states)", startDate);
}
if (!string.IsNullOrEmpty(model.SortBy))
{
if (model.SortOrder != Sorting.@descending)
{
startDate = new object[] { model.SortBy };
sql = sql.OrderBy(startDate);
}
else
{
startDate = new object[] { model.SortBy };
sql = PetaPocoSqlExtensions.OrderByDescending(sql, startDate);
}
}
return sql;
}
public static BaseSearchProvider Current()
{
return ExamineManager.Instance.SearchProviderCollection["FormsSearcher"];
}
public static EntrySearchResultCollection QueryDataBase(RecordFilter model, DatabaseContext databaseContext)
{
EntrySearchResultCollection entrySearchResultCollection;
IMemberService memberService = ApplicationContext.Current.Services.MemberService;
FormStorage formStorage = new FormStorage();
try
{
Form form = formStorage.GetForm(model.Form);
Sql sql = BuildSqlQuery(model, "");
Page<Record> page = databaseContext.Database.Page<Record>((long)model.StartIndex, (long)model.Length, sql);
EntrySearchResultCollection entrySearchResultCollection1 = new EntrySearchResultCollection()
{
TotalNumberOfResults = page.TotalItems,
TotalNumberOfPages = page.TotalPages
};
bool flag = (!Configuration.IsTrial ? false : !Core.Licensing.IsLocalBrowserRequest());
List<EntrySearchResult> entrySearchResults = new List<EntrySearchResult>();
if (form != null)
{
List<EntrySearchResultSchema> entrySearchResultSchemas = new List<EntrySearchResultSchema>();
foreach (Field allField in form.AllFields)
{
if (allField.FieldType.StoresData)
{
EntrySearchResultSchema entrySearchResultSchema = new EntrySearchResultSchema()
{
Name = allField.Caption,
Id = allField.Id.ToString(),
View = allField.FieldType.RenderView
};
entrySearchResultSchemas.Add(entrySearchResultSchema);
}
}
EntrySearchResultSchema entrySearchResultSchema1 = new EntrySearchResultSchema()
{
Id = "member",
View = "member",
Name = "Member"
};
entrySearchResultSchemas.Add(entrySearchResultSchema1);
EntrySearchResultSchema entrySearchResultSchema2 = new EntrySearchResultSchema()
{
Id = "state",
View = "text",
Name = "State"
};
entrySearchResultSchemas.Add(entrySearchResultSchema2);
EntrySearchResultSchema entrySearchResultSchema3 = new EntrySearchResultSchema()
{
Id = "created",
View = "date",
Name = "Created"
};
entrySearchResultSchemas.Add(entrySearchResultSchema3);
EntrySearchResultSchema entrySearchResultSchema4 = new EntrySearchResultSchema()
{
Id = "updated",
View = "date",
Name = "Updated"
};
entrySearchResultSchemas.Add(entrySearchResultSchema4);
entrySearchResultCollection1.schema = entrySearchResultSchemas;
}
foreach (Record item in page.Items)
{
EntrySearchResult entrySearchResult = new EntrySearchResult()
{
Id = item.Id,
Form = item.Form.ToString(),
State = item.StateAsString
};
int localTimeOffset = -model.LocalTimeOffset;
TimeSpan offset = DateTimeOffset.Now.Offset;
int num = localTimeOffset - Convert.ToInt32(offset.TotalMinutes);
DateTime created = item.Created;
entrySearchResult.Created = created.AddMinutes((double)num);
created = item.Updated;
entrySearchResult.Updated = created.AddMinutes((double)num);
entrySearchResult.UniqueId = item.UniqueId;
if (!string.IsNullOrEmpty(item.MemberKey))
{
IMember byId = memberService.GetById(Convert.ToInt32(item.MemberKey));
if (byId != null)
{
entrySearchResult.Member = byId;
}
}
if ((form == null ? false : !string.IsNullOrEmpty(item.RecordData)))
{
Dictionary<string, string> strs = JsonConvert.DeserializeObject<Dictionary<string, string>>(item.RecordData);
List<object> objs = new List<object>();
foreach (EntrySearchResultSchema entrySearchResultSchema5 in entrySearchResultCollection1.schema.Take<EntrySearchResultSchema>(entrySearchResultCollection1.schema.Count<EntrySearchResultSchema>() - 4))
{
if (!strs.ContainsKey(entrySearchResultSchema5.Id))
{
objs.Add(string.Empty);
}
else
{
objs.Add((flag ? Configuration.TrialSaveMessage : strs[entrySearchResultSchema5.Id]));
}
}
objs.Add(entrySearchResult.Member);
objs.Add(entrySearchResult.State);
objs.Add(entrySearchResult.Created);
objs.Add(entrySearchResult.Updated);
entrySearchResult.Fields = objs;
}
entrySearchResults.Add(entrySearchResult);
}
entrySearchResultCollection1.Results = entrySearchResults;
entrySearchResultCollection = entrySearchResultCollection1;
}
finally
{
if (formStorage != null)
{
((IDisposable)formStorage).Dispose();
}
}
return entrySearchResultCollection;
}
public static EntrySearchResultCollection QueryLucene(RecordFilter model)
{
DateTime dateTime;
DateTime dateTime1;
FormStorage formStorage = new FormStorage();
Form form = formStorage.GetForm(model.Form);
formStorage.Dispose();
BaseSearchProvider baseSearchProvider = FormRecordSearcher.Current();
ISearchResults searchResult = baseSearchProvider.Search(BuildLuceneQuery(model, baseSearchProvider));
EntrySearchResultCollection entrySearchResultCollection = new EntrySearchResultCollection()
{
TotalNumberOfResults = (long)searchResult.TotalItemCount
};
List<EntrySearchResult> entrySearchResults = new List<EntrySearchResult>();
if (form != null)
{
List<EntrySearchResultSchema> entrySearchResultSchemas = new List<EntrySearchResultSchema>();
EntrySearchResultSchema entrySearchResultSchema = new EntrySearchResultSchema()
{
Id = "state",
View = "text",
Name = "State"
};
entrySearchResultSchemas.Add(entrySearchResultSchema);
EntrySearchResultSchema entrySearchResultSchema1 = new EntrySearchResultSchema()
{
Id = "created",
View = "date",
Name = "Created"
};
entrySearchResultSchemas.Add(entrySearchResultSchema1);
EntrySearchResultSchema entrySearchResultSchema2 = new EntrySearchResultSchema()
{
Id = "updated",
View = "date",
Name = "Updated"
};
entrySearchResultSchemas.Add(entrySearchResultSchema2);
foreach (Field allField in form.AllFields)
{
if (allField.FieldType.StoresData)
{
EntrySearchResultSchema entrySearchResultSchema3 = new EntrySearchResultSchema()
{
Name = allField.Caption,
Id = allField.Id.ToString(),
View = allField.FieldType.RenderView
};
entrySearchResultSchemas.Add(entrySearchResultSchema3);
}
}
entrySearchResultCollection.schema = entrySearchResultSchemas;
}
foreach (SearchResult searchResult1 in searchResult.Skip(model.StartIndex).Take<SearchResult>(model.Length))
{
EntrySearchResult entrySearchResult = new EntrySearchResult()
{
Score = searchResult1.Score,
Id = searchResult1.Id
};
IDictionary<string, string> fields = searchResult1.Fields;
entrySearchResult.Form = fields["Form"];
entrySearchResult.State = fields["State"];
DateTime.TryParseExact(fields["Created"], "yyyyMMddHHmmssFFF", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime);
DateTime.TryParseExact(fields["Updated"], "yyyyMMddHHmmssFFF", CultureInfo.InvariantCulture, DateTimeStyles.None, out dateTime1);
entrySearchResult.Created = dateTime;
entrySearchResult.Updated = dateTime1;
if (form != null)
{
Dictionary<string, string> strs = JsonConvert.DeserializeObject<Dictionary<string, string>>(fields["Fields"]);
List<object> objs = new List<object>()
{
entrySearchResult.State,
entrySearchResult.Created,
entrySearchResult.Updated
};
foreach (EntrySearchResultSchema entrySearchResultSchema4 in entrySearchResultCollection.schema.Skip<EntrySearchResultSchema>(3))
{
if (!strs.ContainsKey(entrySearchResultSchema4.Id))
{
objs.Add("");
}
else
{
objs.Add(strs[entrySearchResultSchema4.Id]);
}
}
entrySearchResult.Fields = objs;
}
entrySearchResults.Add(entrySearchResult);
}
entrySearchResultCollection.Results = entrySearchResults;
return entrySearchResultCollection;
}
}
}
@ceee
Copy link
Author

ceee commented Jul 13, 2017

New versions of Umbraco.Forms do not expose the FormRecordSearcher.QueryDataBase method for public usage. This method is necessary so that custom ExportTypes can query the form submissions.
This class replaces the FormRecordSearcher and can simple be copied into the project (where Umbraco.Forms is already a dependency).

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