Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • myname 3 posts 73 karma points
    Mar 03, 2021 @ 12:34
    myname
    0

    Umbraco forms - commercial version - how to make custom export type for forms (documentation is wrong/outdated)

    Greetings, I got forms commercial version couple of days ago and I have a requirement for a custom export type at forms so I followed this https://our.umbraco.com/documentation/Add-ons/UmbracoForms/Developer/Extending/Adding-a-Exporttype (the advanced example) but the FormRecordSearcher is giving me (inaccessible due to its protection level) , I also tried this here https://gist.github.com/ceee/3a4053b16f61850baa987a8888e456e6 based on a forum post from 2017 here , found here , https://our.umbraco.com/forum/umbraco-forms/86774-custom-umbraco-forms-export-to-file and it doesn't work too giving me loads of errors and missing references, can someone help me with this, I need to add pdf export type for entries as the example at documentation,

    thank you.

  • myname 3 posts 73 karma points
    Mar 03, 2021 @ 15:56
    myname
    0

    update :

    I implemented this :

    using System;
    

    using System.Collections.Generic; using System.IO; using System.IO.Compression; using System.Linq; using System.Text; using System.Threading.Tasks; using Umbraco.Core; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Services; using Umbraco.Forms; using Umbraco.Forms.Core; using Umbraco.Forms.Core.Models; using Umbraco.Forms.Core.Enums; using Umbraco.Forms.Data.Storage; using Umbraco.Core.Persistence; using System.Globalization; using Umbraco.Forms.Core.Searchers; using Umbraco.Forms.Core.Persistence.Dtos; using Umbraco.Forms.Core.Interfaces; using Umbraco.Core.Scoping; using System.Data; using Newtonsoft.Json; using Umbraco.Core.Models; using NPoco; using Umbraco.Forms.Core.Services; using Umbraco.Web; using Umbraco.Forms.Core.Data.Storage;

    namespace UmbracoPDFexport { public class _formRecordSearcher : IFormRecordSearcher { private readonly IFieldTypeStorage _fieldTypeStorage; private readonly IFormStorage _formStorage; private readonly ILocalizedTextService _localizedTextService; private readonly IMemberService _memberService; private readonly IScopeProvider _scopeProvider; private readonly IUmbracoContextAccessor _umbracoContextAccessor;

        public global::NPoco.Sql BuildSqlQuery(IScope scope, RecordFilter model, string select = "")
        {
            throw new NotImplementedException();
        }
    
        //public EntrySearchResultCollection QueryDataBase(RecordFilter model)
        //{
        //    throw new NotImplementedException();
        //}
        public EntrySearchResultCollection QueryDataBase(RecordFilter model) => this.QueryDataBaseForSubmissions(model, true);
    
        private EntrySearchResultCollection QueryDataBaseForSubmissions(RecordFilter model, bool enforceSensitiveData = true)
        {
            bool? scopeFileSystems = null;
            using (IScope scope = this._scopeProvider.CreateScope(IsolationLevel.Unspecified, RepositoryCacheMode.Unspecified, null, scopeFileSystems, false, false))
            {
                bool flag = this._umbracoContextAccessor.UmbracoContext.Security.CurrentUser.HasAccessToSensitiveData();
                Form form = this._formStorage.GetForm(model.Form);
                Sql sql = this.BuildSqlQuery(scope, model, "");
                Page<Record> page = scope.Database.Page<Record>((long)model.StartIndex, (long)model.Length, sql);
                EntrySearchResultCollection collection1 = new EntrySearchResultCollection();
                collection1.TotalNumberOfResults = page.TotalItems;
                collection1.TotalNumberOfPages = page.TotalPages;
                EntrySearchResultCollection results = collection1;
                //bool flag2 = Configuration.IsTrial && !Licensing.IsLocalBrowserRequest();
                List<EntrySearchResult> list = new List<EntrySearchResult>();
                if (form != null)
                {
                    List<EntrySearchResultSchema> list2 = new List<EntrySearchResultSchema>();
                    foreach (Field field in form.AllFields)
                    {
                        FieldType fieldTypeByField = this._fieldTypeStorage.GetFieldTypeByField(field);
                        if (fieldTypeByField.StoresData)
                        {
                            EntrySearchResultSchema schema1 = new EntrySearchResultSchema();
                            schema1.Name = field.Caption;
                            schema1.Id = field.Id.ToString();
                            schema1.View = fieldTypeByField.RenderView;
                            EntrySearchResultSchema schema = schema1;
                            if (field.ContainsSensitiveData)
                            {
                                schema.ContainsSensitiveData = true;
                            }
                            list2.Add(schema);
                        }
                    }
                    EntrySearchResultSchema item = new EntrySearchResultSchema();
                    item.Id = "member";
                    item.View = "member";
                    item.Name = "Member";
                    item.ContainsSensitiveData = true;
                    list2.Add(item);
                    EntrySearchResultSchema schema4 = new EntrySearchResultSchema();
                    schema4.Id = "state";
                    schema4.View = "text";
                    schema4.Name = "State";
                    list2.Add(schema4);
                    EntrySearchResultSchema schema5 = new EntrySearchResultSchema();
                    schema5.Id = "created";
                    schema5.View = "date";
                    schema5.Name = "Created";
                    list2.Add(schema5);
                    EntrySearchResultSchema schema6 = new EntrySearchResultSchema();
                    schema6.Id = "updated";
                    schema6.View = "date";
                    schema6.Name = "Updated";
                    list2.Add(schema6);
                    results.schema = list2;
                }
                foreach (Record record in page.Items)
                {
                    EntrySearchResult result1 = new EntrySearchResult();
                    result1.Id = record.Id;
                    result1.Form = record.Form.ToString();
                    result1.State = record.StateAsString;
                    EntrySearchResult item = result1;
                    int num = -model.LocalTimeOffset;
                    DateTimeOffset now = DateTimeOffset.Now;
                    TimeSpan offset = now.Offset;
                    int num2 = Convert.ToInt32(offset.TotalMinutes);
                    int num3 = num - num2;
                    item.Created = record.Created.AddMinutes((double)num3);
                    item.Updated = record.Updated.AddMinutes((double)num3);
                    item.UniqueId = record.UniqueId;
                    try
                    {
                        if (!string.IsNullOrEmpty(record.MemberKey))
                        {
                            IMember byId = this._memberService.GetById(Convert.ToInt32(record.MemberKey));
                            if (byId != null)
                            {
                                item.Member = byId;
                            }
                        }
                    }
                    catch (Exception ex)
                    {
    
                        //do nothing
                    }
                    if ((form != null) && !string.IsNullOrEmpty(record.RecordData))
                    {
                        Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(record.RecordData);
                        List<object> list3 = new List<object>();
                        string str = _localizedTextService.Localize("content/isSensitiveValue", CultureInfo.CurrentCulture, null);
                        foreach (EntrySearchResultSchema schema2 in results.schema.Take<EntrySearchResultSchema>(results.schema.Count<EntrySearchResultSchema>() - 4))
                        {
                            if (!dictionary.ContainsKey(schema2.Id))
                            {
                                list3.Add(string.Empty);
                                continue;
                            }
                            //if (flag2)
                            //{
                            //    list3.Add(Configuration.TrialSaveMessage);
                            //    continue;
                            //}
                            if ((flag || !schema2.ContainsSensitiveData) ? (enforceSensitiveData && schema2.ContainsSensitiveData) : true)
                            {
                                list3.Add(str);
                                continue;
                            }
                            list3.Add(dictionary[schema2.Id]);
                        }
                        try
                        {
                            list3.Add(item.Member);
                        }
                        catch (Exception ex)
                        {
    
                           //do nothing
                        }
                        list3.Add(item.State);
                        list3.Add(item.Created);
                        list3.Add(item.Updated);
                        item.Fields = list3;
                    }
                    list.Add(item);
                }
                results.Results = list;
                scope.Complete();
                return results;
            }
        }
    }
    public class ExportToTextFile : ExportType
    {
        public ExportToTextFile()
        {
            this.Name = "Export as pdf files";
            this.Description = "Export entries as pdf files inside a zip file";
            this.Id = new Guid("171CABC9-2207-4575-83D5-2A77E824D5DB");
            this.FileExtension = "zip";
            this.Icon = "icon-zip";
        }
    
        /// <summary>
        /// We do not implement this method from the interface
        /// As this method is called from ExportToFile that we also override here & is expecting the file contents as a string to be written as a stream to a file
        /// Which would be OK if we were creating a CSV or a single based file that can have a simple string written as a string such as one large HTML report or XML file perhaps
        /// </summary>
    
        public override string ExportRecords(RecordExportFilter filter)
        {
            throw new NotImplementedException();
        }
    
        /// <summary>
        /// This gives us greater control of the export process
        /// </summary>
        /// <param name="filter">
        /// This filter contains the date range & other search parameters to limit the entries we are exporting
        /// </param>
        /// <param name="filepath">
        /// The filepath that the export file is expecting to be served from
        /// So ensure that the zip of text files is saved at this location
        /// </param>
        /// <returns>The final file path to serve up as the export - this is unlikely to change through the export logic</returns>
        public override string ExportToFile(RecordExportFilter filter, string filepath)
        {
            // Before Save - Check Path, Directory & Previous File export does not exist
            string pathToSaveZipFile = filepath;
    
            // Check our path does not contain \\
            // If not, use the filePath
            if (filepath.Contains('\\') == false)
            {
                pathToSaveZipFile = IOHelper.MapPath(filepath);
            }
    
            // Get the directory (strip out \\ if it exists)
            var dir = filepath.Substring(0, filepath.LastIndexOf('\\'));
            var tempFileDir = Path.Combine(dir, "text-files");
    
    
            // If the path does not end with our file extension, ensure it's added
            if (pathToSaveZipFile.EndsWith("." + FileExtension) == false)
            {
                pathToSaveZipFile += "." + FileExtension;
            }
    
            // Check that the directory where we will save the ZIP file temporarily exists
            // If not just create it
            if (Directory.Exists(tempFileDir) == false)
            {
                Directory.CreateDirectory(tempFileDir);
            }
    
            // Check if the zip file exists already - if so delete it, as we have a new update
            if (System.IO.File.Exists(pathToSaveZipFile))
            {
                System.IO.File.Delete(pathToSaveZipFile);
            }
    
    
            // Query the DB for submissions to export based on the filter
    
            _formRecordSearcher recordSearcher = new _formRecordSearcher();
            EntrySearchResultCollection submissions = recordSearcher.QueryDataBase(filter);
    
            // Get the schema objects to a list so we can get items using position index
            var schemaItems = submissions.schema.ToList();
    
            // We will use this to store our contents of our file to save as a text file
            var fileContents = string.Empty;
    
            // For each submission we have build up a string to save to a text file
            foreach (var submission in submissions.Results)
            {
                // The submitted data for the form submission
                var submissionData = submission.Fields.ToList();
    
                // For loop to match the schema position to the submission data
                for (int i = 0; i < schemaItems.Count; i++)
                {
                    // Concat a string of the name of the field & its stored data
                    fileContents += schemaItems[i].Name + ": " + submissionData[i] + Environment.NewLine;
                }
    
                // Now save the contents to a text file
                // Base it on the format of the record submission unique id
                var textFileName = Path.Combine(tempFileDir, submission.UniqueId + ".pdf");
                System.IO.File.WriteAllText(textFileName, fileContents);
    
                // Reset fileContents to be empty again
                fileContents = string.Empty;
            }
    
            // Now we have a temp folder full of text files
            // Generate a zip file containing them & save that
            ZipFile.CreateFromDirectory(tempFileDir, pathToSaveZipFile);
    
            // Tidy up after ourselves & delete the temp folder of text files
            if (Directory.Exists(tempFileDir))
            {
                Directory.Delete(tempFileDir, true);
            }
    
            // Return the path where we saved the zip file containing the text files
            return pathToSaveZipFile;
        }
    
    }
    

    and it is giving me a weird error :

    Possibly unhandled rejection: {"data":{"Message":"An error has occurred.","ExceptionMessage":"Object reference not set to an instance of an object.","ExceptionType":"System.NullReferenceException","StackTrace":"   at UmbracoPDFexport._formRecordSearcher.QueryDataBaseForSubmissions(RecordFilter model, Boolean enforceSensitiveData)\r\n   at UmbracoPDFexport._formRecordSearcher.QueryDataBase(RecordFilter model)\r\n   at UmbracoPDFexport.ExportToTextFile.ExportToFile(RecordExportFilter filter, String filepath)\r\n   at Umbraco.Forms.Web.Editors.ExportController.PostGenerateExport(RecordExportFilter model)\r\n   at lambda_method(Closure , Object , Object[] )\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.<>c__DisplayClass6_2.<GetExecutor>b__2(Object instance, Object[] methodParameters)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ActionExecutor.Execute(Object instance, Object[] arguments)\r\n   at System.Web.Http.Controllers.ReflectedHttpActionDescriptor.ExecuteAsync(HttpControllerContext controllerContext, IDictionary`2 arguments, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ApiControllerActionInvoker.<InvokeActionAsyncCore>d__1.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<CallOnActionExecutedAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.ActionFilterAttribute.<ExecuteActionFilterAsyncCore>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ActionFilterResult.<ExecuteAsync>d__5.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Filters.AuthorizationFilterAttribute.<ExecuteAuthorizationFilterAsyncCore>d__3.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Web.Http.Controllers.ExceptionFilterResult.<ExecuteAsync>d__6.MoveNext()\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__15.MoveNext()"},"status":500,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"jsonpCallbackParam":"callback","url":"backoffice/UmbracoForms/Export/PostGenerateExport","data":{"startIndex":1,"length":20,"form":"b2413bd7-54f0-46eb-a7ad-0fde030638f1","sortBy":"created","sortOrder":"descending","states":["Approved","Submitted"],"localTimeOffset":-120,"exportType":"171cabc9-2207-4575-83d5-2a77e824d5db"},"headers":{"Accept":"application/json, text/plain, */*","Content-Type":"application/json;charset=utf-8","X-Requested-With":"XMLHttpRequest","X-UMB-XSRF-TOKEN":"BZoVuqZZ8PZ4WL-xVe57KWIHU1cQR8u33G9G0PPFD-P4zmp6jbK9N2k1I6dC4KfJ74kYl6mPIhXCO-bnvpWy5HlWSH2Pu0CbgmbkEp4XRd9bq1XW3jN4SsMSmBVMgf2yCZCihMUAFknk-HEXWgn20Q2"}},"statusText":"","xhrStatus":"complete"}
    

    does anyone have any idea what is this?

    thank you.

Please Sign in or register to post replies

Write your reply to:

Draft