├── src ├── WFFM.ConversionTool │ ├── Analysis │ │ └── readme.txt │ ├── packages.config │ ├── Metadata │ │ ├── Fields │ │ │ ├── Email.json │ │ │ ├── DatePicker.json │ │ │ ├── Password.json │ │ │ ├── Telephone.json │ │ │ ├── RadioButtonList.json │ │ │ ├── SingleLineText.json │ │ │ ├── CheckboxList.json │ │ │ ├── Number.json │ │ │ ├── FileUpload.json │ │ │ ├── MultipleLineText.json │ │ │ ├── DropdownList.json │ │ │ ├── Checkbox.json │ │ │ ├── ListBox.json │ │ │ ├── Input.json │ │ │ ├── Date.json │ │ │ ├── PasswordConfirmation.json │ │ │ ├── List.json │ │ │ ├── Text.json │ │ │ └── Button.json │ │ ├── Folder.json │ │ ├── Form.json │ │ ├── EmailAddress.json │ │ ├── ExtendedListItem.json │ │ ├── SubmitActionDefinition.json │ │ ├── BaseTemplate.json │ │ ├── Section.json │ │ ├── Page.json │ │ └── Field.json │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── App.config │ ├── AppSettings.json │ └── Program.cs ├── WFFM.ConversionTool.Library │ ├── Migrators │ │ └── IDataMigrator.cs │ ├── Validators │ │ ├── IValidator.cs │ │ ├── AppSettingsValidator.cs │ │ ├── DbConnectionStringValidator.cs │ │ └── MetadataValidator.cs │ ├── Processors │ │ ├── IFormProcessor.cs │ │ ├── IItemProcessor.cs │ │ └── ItemProcessor.cs │ ├── Providers │ │ ├── FormsData │ │ │ ├── IDataProvider.cs │ │ │ ├── SqlDataReader.cs │ │ │ └── MongoDbDataReader.cs │ │ ├── IFieldProvider.cs │ │ ├── IMetadataProvider.cs │ │ └── FieldProvider.cs │ ├── Models │ │ ├── Form │ │ │ ├── SaveAction.cs │ │ │ └── SendEmailAction.cs │ │ ├── Sitecore │ │ │ ├── SCItem.cs │ │ │ └── SCField.cs │ │ ├── Reporting │ │ │ └── ReportingRecord.cs │ │ └── Metadata │ │ │ ├── AppSettings.cs │ │ │ └── MetadataTemplate.cs │ ├── Constants │ │ ├── TextConstants.cs │ │ ├── MediaItemConstants.cs │ │ ├── ButtonConstants.cs │ │ ├── BaseTemplateConstants.cs │ │ ├── EmailAddressConstants.cs │ │ ├── SectionConstants.cs │ │ ├── SubmitActionConstants.cs │ │ └── FormConstants.cs │ ├── Converters │ │ ├── IItemConverter.cs │ │ ├── FieldConverters │ │ │ ├── YesNoConverter.cs │ │ │ ├── SelectionModeConverter.cs │ │ │ ├── TrackingConverter.cs │ │ │ ├── DateConverter.cs │ │ │ ├── SelectedValueConverter.cs │ │ │ └── DatasourceConverter.cs │ │ ├── FieldValueConverters │ │ │ ├── BooleanConverter.cs │ │ │ ├── DateValueConverter.cs │ │ │ └── FileUploadConverter.cs │ │ ├── IFieldConverter.cs │ │ ├── BaseFieldConverter.cs │ │ ├── SubmitActionConverters │ │ │ └── SendEmailConverter.cs │ │ ├── SectionAppearanceConverter.cs │ │ └── FormAppearanceConverter.cs │ ├── Repositories │ │ ├── ISitecoreFormsDbRepository.cs │ │ ├── ISourceMasterRepository.cs │ │ ├── IDestMasterRepository.cs │ │ ├── SitecoreFormsDbRepository.cs │ │ └── SourceMasterRepository.cs │ ├── Database │ │ ├── WFFM │ │ │ ├── FieldData.cs │ │ │ ├── WFFM.cs │ │ │ └── FormData.cs │ │ ├── MongoDB │ │ │ ├── FieldData.cs │ │ │ ├── FormData.cs │ │ │ └── MongoAnalytics.cs │ │ ├── Forms │ │ │ ├── FileStorage.cs │ │ │ ├── FieldData.cs │ │ │ ├── SitecoreForms.cs │ │ │ └── FormEntry.cs │ │ ├── Master │ │ │ ├── DestMasterDb.cs │ │ │ ├── SourceMasterDb.cs │ │ │ ├── SharedField.cs │ │ │ ├── Blob.cs │ │ │ ├── Item.cs │ │ │ ├── UnversionedField.cs │ │ │ └── VersionedField.cs │ │ └── ConnectionTester.cs │ ├── Factories │ │ ├── IFieldFactory.cs │ │ ├── IItemFactory.cs │ │ ├── FieldFactory.cs │ │ └── ItemFactory.cs │ ├── Logging │ │ ├── Log4NetTraceListener.cs │ │ ├── ILogger.cs │ │ └── Log4NetAdapter.cs │ ├── Reporting │ │ ├── IReporter.cs │ │ └── AnalysisReporter.cs │ ├── packages.config │ ├── Visualization │ │ └── ProgressBar.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── Helpers │ │ └── XmlHelper.cs │ └── IoC.cs └── WFFM.ConversionTool.Extensions.SitecoreFormsExtensions │ ├── readme_SitecoreFormsExtensions.txt │ ├── Metadata │ └── Custom │ │ └── ReCaptcha.json │ ├── Properties │ └── AssemblyInfo.cs │ └── WFFM.ConversionTool.Extensions.SitecoreFormsExtensions.csproj ├── .github └── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── LICENSE ├── .gitignore └── WFFM.ConversionTool.sln /src/WFFM.ConversionTool/Analysis/readme.txt: -------------------------------------------------------------------------------- 1 | This folder stores the generated conversion analysis reports. -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Migrators/IDataMigrator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WFFM.ConversionTool.Library.Migrators 4 | { 5 | public interface IDataMigrator 6 | { 7 | void MigrateData(); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Validators/IValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Validators 8 | { 9 | public interface IValidator 10 | { 11 | bool Validate(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Processors/IFormProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Processors 8 | { 9 | public interface IFormProcessor 10 | { 11 | List ConvertForms(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Extensions.SitecoreFormsExtensions/readme_SitecoreFormsExtensions.txt: -------------------------------------------------------------------------------- 1 | +------------------------------------------------------+ 2 | | Installation Instructions | 3 | +------------------------------------------------------+ 4 | 5 | 1) Copy the entire module extension folder in the WFFM Conversion Tool root folder. When prompted, choose to merge the existing folders. 6 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/FormsData/IDataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using WFFM.ConversionTool.Library.Database.WFFM; 4 | 5 | namespace WFFM.ConversionTool.Library.Providers.FormsData 6 | { 7 | public interface IDataProvider 8 | { 9 | List GetFormDataRecords(Guid formItemId); 10 | List GetFieldDataRecords(Guid formDataId); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Form/SaveAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Models.Form 8 | { 9 | public class SaveAction 10 | { 11 | public string Id { get; set; } 12 | public string UnicId { get; set; } 13 | public string Parameters { get; set; } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/TextConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class TextConstants 10 | { 11 | public const string TextFieldId = "{9666782B-21BB-40CE-B38F-8F6C53FA5070}"; 12 | public const string TextHtmlTagFieldId = "{C6CAA979-C3AC-4FFC-861E-2961F5FC3C48}"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/IItemConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Converters 10 | { 11 | public interface IItemConverter 12 | { 13 | List Convert(SCItem scItem, Guid destParentId); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/MediaItemConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class MediaItemConstants 10 | { 11 | public const string ExtensionFieldId = "{C06867FE-9A43-4C7D-B739-48780492D06F}"; 12 | public const string MediaFieldId = "{40E50ED9-BA07-4702-992E-A912738D32DC}"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/ButtonConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class ButtonConstants 10 | { 11 | public const string ButtonNavigationFieldId = "{D842AF43-E220-48D7-9714-6EB2381D2B0C}"; 12 | public const string ButtonTitleFIeldId = "{71FFD7B2-8B09-4F7B-8A66-1E4CEF653E8D}"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/BaseTemplateConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class BaseTemplateConstants 10 | { 11 | public const string SortOrderFieldId = "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}"; 12 | public const string DisplayNameFieldId = "{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}"; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/YesNoConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 8 | { 9 | public class YesNoConverter : BaseFieldConverter 10 | { 11 | public override string ConvertValue(string sourceValue) 12 | { 13 | return sourceValue.ToLower() == "yes" ? "1" : ""; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Repositories/ISitecoreFormsDbRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using WFFM.ConversionTool.Library.Database.Forms; 4 | 5 | namespace WFFM.ConversionTool.Library.Repositories 6 | { 7 | public interface ISitecoreFormsDbRepository 8 | { 9 | void CreateOrUpdateFormData(FormEntry formEntry); 10 | void DeleteFieldDataByFormRecordId(Guid formRecordId); 11 | void CreateOrUpdateFileStorageFormRecord(FileStorage fileStorage); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **Sitecore Platform Details** 14 | * Source Sitecore Version: 15 | * WFFM Module Version: 16 | * Destination Sitecore Version: 17 | * Forms Data Provider (sql / mongodb): 18 | 19 | **Additional information** 20 | Add any other information about the problem here. 21 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/IFieldProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Sitecore; 7 | 8 | namespace WFFM.ConversionTool.Library.Providers 9 | { 10 | public interface IFieldProvider 11 | { 12 | Dictionary, string> GetFieldValues(SCItem sourceItem, Guid sourceFieldId, string defaultValue, 13 | bool stripHtml = false); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/SelectionModeConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 8 | { 9 | public class SelectionModeConverter : BaseFieldConverter 10 | { 11 | public override string ConvertValue(string sourceValue) 12 | { 13 | return sourceValue.ToLower() == "multiple" ? "1" : ""; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Form/SendEmailAction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Models.Form 8 | { 9 | public class SendEmailAction 10 | { 11 | public string from { get; set; } 12 | public string to { get; set; } 13 | public string cc { get; set; } 14 | public string bcc { get; set; } 15 | public string subject { get; set; } 16 | public string body { get; set; } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/EmailAddressConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class EmailAddressConstants 10 | { 11 | // Senders Setting Folder 12 | public const string EmailAddressSendersFolderId = "{E52AB5AD-3202-4B6F-9BAD-80B049C403EA}"; 13 | 14 | // FieldId 15 | public const string EmailAddressValueFieldId = "{49DC3FF7-C17D-4574-B88E-2418DCE1315F}"; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldValueConverters/BooleanConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Converters.FieldValueConverters 8 | { 9 | public class BooleanConverter : BaseFieldConverter 10 | { 11 | public override string ConvertValue(string sourceValue) 12 | { 13 | return string.Equals(sourceValue, "1", StringComparison.InvariantCultureIgnoreCase) ? "True" : "False"; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Sitecore/SCItem.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace WFFM.ConversionTool.Library.Models.Sitecore 5 | { 6 | public class SCItem 7 | { 8 | public Guid ID { get; set; } 9 | public string Name { get; set; } 10 | public Guid TemplateID { get; set; } 11 | public Guid MasterID { get; set; } 12 | public Guid ParentID { get; set; } 13 | public DateTime Created { get; set; } 14 | public DateTime Updated { get; set; } 15 | public List Fields { get; set; } 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/WFFM/FieldData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace WFFM.ConversionTool.Library.Database.WFFM 5 | { 6 | [Table("FieldData")] 7 | public partial class FieldData 8 | { 9 | public Guid Id { get; set; } 10 | 11 | public Guid FormId { get; set; } 12 | 13 | public Guid FieldItemId { get; set; } 14 | 15 | public string FieldName { get; set; } 16 | 17 | public string Value { get; set; } 18 | 19 | public string Data { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/WFFM/WFFM.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Entity; 2 | 3 | namespace WFFM.ConversionTool.Library.Database.WFFM 4 | { 5 | public partial class WFFM : DbContext 6 | { 7 | public WFFM(string nameOrConnectionString) 8 | : base(nameOrConnectionString) 9 | { 10 | } 11 | 12 | public virtual DbSet FieldDatas { get; set; } 13 | public virtual DbSet FormDatas { get; set; } 14 | 15 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 16 | { 17 | } 18 | } 19 | 20 | public interface IContext 21 | { 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/WFFM/FormData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.DataAnnotations.Schema; 3 | 4 | namespace WFFM.ConversionTool.Library.Database.WFFM 5 | { 6 | [Table("FormData")] 7 | public partial class FormData 8 | { 9 | public Guid Id { get; set; } 10 | 11 | public Guid FormItemId { get; set; } 12 | 13 | public Guid ContactId { get; set; } 14 | 15 | public Guid InteractionId { get; set; } 16 | 17 | public DateTime TimeStamp { get; set; } 18 | 19 | public string Data { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/TrackingConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 10 | { 11 | public class TrackingConverter : BaseFieldConverter 12 | { 13 | public override string ConvertValue(string sourceValue) 14 | { 15 | return sourceValue.Replace(" ","").Contains("") ? string.Empty : "1"; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/MongoDB/FieldData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MongoDB.Bson.Serialization.Attributes; 7 | 8 | namespace WFFM.ConversionTool.Library.Database.MongoDB 9 | { 10 | public class FieldData 11 | { 12 | [BsonElement("Data")] 13 | public string Data { get; set; } 14 | [BsonElement("FieldId")] 15 | public Guid FieldId { get; set; } 16 | [BsonElement("FieldName")] 17 | public string FieldName { get; set; } 18 | [BsonElement("Value")] 19 | public string Value { get; set; } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Factories/IFieldFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Metadata; 8 | using WFFM.ConversionTool.Library.Models.Sitecore; 9 | 10 | namespace WFFM.ConversionTool.Library.Factories 11 | { 12 | public interface IFieldFactory 13 | { 14 | List CreateFields(MetadataTemplate.MetadataFields.MetadataNewField metadataNewField, Guid itemId, IEnumerable> langVersions, IEnumerable languages); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Sitecore/SCField.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WFFM.ConversionTool.Library.Models.Sitecore 4 | { 5 | public class SCField 6 | { 7 | public string Value { get; set; } 8 | public Guid Id { get; set; } 9 | public Guid FieldId { get; set; } 10 | public Guid ItemId { get; set; } 11 | public DateTime Created { get; set; } 12 | public DateTime Updated { get; set; } 13 | public FieldType Type { get; set; } 14 | public int? Version { get; set; } 15 | public string Language { get; set; } 16 | } 17 | 18 | public enum FieldType 19 | { 20 | Shared, 21 | Versioned, 22 | Unversioned 23 | } 24 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Factories/IItemFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Metadata; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Factories 10 | { 11 | public interface IItemFactory 12 | { 13 | SCItem Create(Guid destTemplateId, SCItem parentItem, string itemName, MetadataTemplate metadataTemplate = null); 14 | List CreateDescendantItems(MetadataTemplate _metadataTemplate, SCItem destItem); 15 | SCItem CreateDummyItem(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/IMetadataProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Microsoft.SqlServer.Server; 7 | using WFFM.ConversionTool.Library.Models.Metadata; 8 | 9 | namespace WFFM.ConversionTool.Library.Providers 10 | { 11 | public interface IMetadataProvider 12 | { 13 | MetadataTemplate GetItemMetadataByTemplateId(Guid templateId); 14 | MetadataTemplate GetItemMetadataByTemplateName(string templateName); 15 | MetadataTemplate GetItemMetadataBySourceMappingFieldValue(string mappingValue); 16 | string[] GetAllMetadataFiles(); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Processors/IItemProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Metadata; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Processors 10 | { 11 | public interface IItemProcessor 12 | { 13 | void ConvertAndWriteItem(SCItem sourceItem, Guid parentId); 14 | Guid WriteNewItem(Guid destTemplateId, SCItem parentItem, string itemName, MetadataTemplate metadataTemplate); 15 | void UpdateItem(SCItem item); 16 | void WriteDescendentItems(MetadataTemplate metadataTemplate, SCItem parentItem); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/DateConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 9 | { 10 | public class DateConverter : BaseFieldConverter 11 | { 12 | public override string ConvertValue(string sourceValue) 13 | { 14 | DateTime sourceDate; 15 | if (DateTime.TryParseExact(sourceValue, "yyyyMMddThhmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out sourceDate)) 16 | { 17 | return sourceDate.ToUniversalTime().ToString("yyyyMMddThhmmssZ"); 18 | } 19 | return sourceValue; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldValueConverters/DateValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Globalization; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace WFFM.ConversionTool.Library.Converters.FieldValueConverters 9 | { 10 | public class DateValueConverter : BaseFieldConverter 11 | { 12 | public override string ConvertValue(string sourceValue) 13 | { 14 | DateTime sourceDate; 15 | if (DateTime.TryParseExact(sourceValue, "yyyyMMddThhmmss", CultureInfo.InvariantCulture, DateTimeStyles.None, out sourceDate)) 16 | { 17 | return sourceDate.ToString("M/d/yyyy hh:mm:ss tt"); 18 | } 19 | return sourceValue; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/MongoDB/FormData.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MongoDB.Bson; 7 | using MongoDB.Bson.Serialization.Attributes; 8 | 9 | namespace WFFM.ConversionTool.Library.Database.MongoDB 10 | { 11 | public class FormData 12 | { 13 | [BsonId] 14 | public Guid Id { get; set; } 15 | [BsonElement("FormID")] 16 | public Guid FormId { get; set; } 17 | [BsonElement("ContactId")] 18 | public Guid ContactId { get; set; } 19 | [BsonElement("InteractionId")] 20 | public Guid InteractionId { get; set; } 21 | [BsonElement("Timestamp")] 22 | public DateTime Timestamp { get; set; } 23 | [BsonElement("Fields")] 24 | public List FieldDatas { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/SectionConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class SectionConstants 10 | { 11 | public const string SectionTitleFieldId = "{821724F3-30BB-4152-A770-88BC43AC175A}"; 12 | public const string SectionParametersFieldId = "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}"; 13 | public const string SectionLocalizedParametersFieldId = "{26CDC7C2-5307-4591-A7F9-5C034A05630A}"; 14 | public const string SectionShowLegendElementName = "ShowLegend"; 15 | public const string SectionInformationElementName = "Information"; 16 | public const string SectionTitleTagValue = "h2"; 17 | public const string SectionInformationTagValue = "p"; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Repositories/ISourceMasterRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Repositories 10 | { 11 | public interface ISourceMasterRepository 12 | { 13 | SCItem GetSitecoreItem(Guid itemId); 14 | List GetSitecoreItems(Guid templateId); 15 | bool ItemHasChildrenOfTemplate(Guid templateId, SCItem scItem); 16 | List GetSitecoreChildrenItems(Guid templateId, Guid parentId); 17 | string GetSitecoreItemName(Guid itemId); 18 | string GetItemPath(Guid itemId); 19 | Guid GetItemTemplateId(Guid itemId); 20 | byte[] GetSitecoreBlobData(Guid blobId); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Forms/FileStorage.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Forms 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | [Table("sitecore_forms_filestorage.FileStorage")] 10 | public partial class FileStorage 11 | { 12 | public Guid Id { get; set; } 13 | 14 | [Required] 15 | [StringLength(256)] 16 | public string FileName { get; set; } 17 | 18 | [Column(TypeName = "datetime2")] 19 | public DateTime Created { get; set; } 20 | 21 | public bool Committed { get; set; } 22 | 23 | [Required] 24 | public byte[] FileContent { get; set; } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/FormsData/SqlDataReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using WFFM.ConversionTool.Library.Database.WFFM; 5 | 6 | namespace WFFM.ConversionTool.Library.Providers.FormsData 7 | { 8 | public class SqlDataProvider : IDataProvider 9 | { 10 | private Database.WFFM.WFFM _wffmDatabase; 11 | 12 | public SqlDataProvider(Database.WFFM.WFFM wffmDatabase) 13 | { 14 | _wffmDatabase = wffmDatabase; 15 | } 16 | 17 | public List GetFormDataRecords(Guid formItemId) 18 | { 19 | return _wffmDatabase.FormDatas.Where(x => x.FormItemId == formItemId).ToList(); 20 | } 21 | 22 | public List GetFieldDataRecords(Guid formDataId) 23 | { 24 | return _wffmDatabase.FieldDatas.Where(f => f.FormId == formDataId).ToList(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/DestMasterDb.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Data.Entity; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | using System.Linq; 7 | 8 | public partial class DestMasterDb : DbContext 9 | { 10 | public DestMasterDb(string nameOrConnectionString) 11 | : base(nameOrConnectionString) 12 | { 13 | } 14 | 15 | public virtual DbSet Blobs { get; set; } 16 | public virtual DbSet Items { get; set; } 17 | public virtual DbSet SharedFields { get; set; } 18 | public virtual DbSet UnversionedFields { get; set; } 19 | public virtual DbSet VersionedFields { get; set; } 20 | 21 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/SourceMasterDb.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Data.Entity; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | using System.Linq; 7 | 8 | public partial class SourceMasterDb : DbContext 9 | { 10 | public SourceMasterDb(string nameOrConnectionString) 11 | : base(nameOrConnectionString) 12 | { 13 | } 14 | 15 | public virtual DbSet Blobs { get; set; } 16 | public virtual DbSet Items { get; set; } 17 | public virtual DbSet SharedFields { get; set; } 18 | public virtual DbSet UnversionedFields { get; set; } 19 | public virtual DbSet VersionedFields { get; set; } 20 | 21 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 22 | { 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Repositories/IDestMasterRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Repositories 10 | { 11 | public interface IDestMasterRepository 12 | { 13 | void AddOrUpdateSitecoreItem(SCItem scItem); 14 | void DeleteSitecoreItem(SCItem scItem); 15 | bool ItemHasChildrenOfTemplate(Guid templateId, SCItem scItem); 16 | 17 | List GetSitecoreChildrenItems(Guid templateId, Guid parentId); 18 | List GetSitecoreDescendantsItems(Guid templateId, Guid parentId); 19 | List GetSitecoreDescendantsItems(Guid parentId); 20 | SCItem GetSitecoreItem(Guid itemId); 21 | bool ItemExists(Guid itemId); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/IFieldConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models; 7 | using WFFM.ConversionTool.Library.Models.Metadata; 8 | using WFFM.ConversionTool.Library.Models.Sitecore; 9 | 10 | namespace WFFM.ConversionTool.Library.Converters 11 | { 12 | public interface IFieldConverter 13 | { 14 | string ConvertValue(string sourceValue); 15 | SCField ConvertField(SCField scField, Guid destFieldId); 16 | SCField ConvertValueElement(SCField scField, Guid destFieldId, string elementValue, List destItems = null); 17 | List ConvertValueElementToItems(SCField scField, string elementValue, MetadataTemplate metadataTemplate, SCItem sourceItem); 18 | List ConvertValueElementToFields(SCField scField, string elementValue); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Forms/FieldData.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Forms 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | [Table("sitecore_forms_storage.FieldData")] 10 | public partial class FieldData 11 | { 12 | public Guid Id { get; set; } 13 | 14 | public Guid FormEntryId { get; set; } 15 | 16 | public Guid FieldDefinitionId { get; set; } 17 | 18 | [Required] 19 | [StringLength(256)] 20 | public string FieldName { get; set; } 21 | 22 | public string Value { get; set; } 23 | 24 | [StringLength(256)] 25 | public string ValueType { get; set; } 26 | 27 | public virtual FormEntry FormEntry { get; set; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Logging/Log4NetTraceListener.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Logging 8 | { 9 | public class Log4NetTraceListener : System.Diagnostics.TraceListener 10 | { 11 | private readonly log4net.ILog _log; 12 | 13 | public Log4NetTraceListener() 14 | { 15 | _log = log4net.LogManager.GetLogger("System.Diagnostics.Redirection"); 16 | } 17 | 18 | public Log4NetTraceListener(log4net.ILog log) 19 | { 20 | _log = log; 21 | } 22 | 23 | public override void Write(string message) 24 | { 25 | if (_log != null) 26 | { 27 | _log.Debug(message); 28 | } 29 | } 30 | 31 | public override void WriteLine(string message) 32 | { 33 | if (_log != null) 34 | { 35 | _log.Debug(message); 36 | } 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/SharedField.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | public partial class SharedField 10 | { 11 | [Key] 12 | [Column(Order = 0)] 13 | public Guid Id { get; set; } 14 | 15 | [Column(Order = 1)] 16 | public Guid ItemId { get; set; } 17 | 18 | [Column(Order = 2)] 19 | public Guid FieldId { get; set; } 20 | 21 | [Column(Order = 3)] 22 | [MaxLength] 23 | public string Value { get; set; } 24 | 25 | [Column(Order = 4)] 26 | public DateTime Created { get; set; } 27 | 28 | [Column(Order = 5)] 29 | public DateTime Updated { get; set; } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Reporting/IReporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Metadata; 7 | using WFFM.ConversionTool.Library.Models.Reporting; 8 | using WFFM.ConversionTool.Library.Models.Sitecore; 9 | 10 | namespace WFFM.ConversionTool.Library.Reporting 11 | { 12 | public interface IReporter 13 | { 14 | string CurrentFormId { get; set; } 15 | string CurrentFormName { get; set; } 16 | 17 | void AddUnmappedItemField(SCField field, Guid itemId); 18 | void AddUnmappedFormFieldItem(Guid itemId, string sourceMappingFieldValue); 19 | void AddUnmappedSaveAction(SCField field, Guid itemId, Guid saveActionId); 20 | 21 | void AddUnmappedValueElementSourceField(SCField field, Guid itemId, string sourceFieldValueElementName, string sourceFieldValueElementValue); 22 | void GenerateOutput(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/Blob.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | public partial class Blob 10 | { 11 | [Key] 12 | [Column(Order = 0)] 13 | public Guid Id { get; set; } 14 | 15 | [Key] 16 | [Column(Order = 1)] 17 | public Guid BlobId { get; set; } 18 | 19 | [Key] 20 | [Column(Order = 2)] 21 | [DatabaseGenerated(DatabaseGeneratedOption.None)] 22 | public int Index { get; set; } 23 | 24 | [Key] 25 | [Column(Order = 3, TypeName = "image")] 26 | public byte[] Data { get; set; } 27 | 28 | [Key] 29 | [Column(Order = 4)] 30 | public DateTime Created { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Logging/ILogger.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Logging 8 | { 9 | public interface ILogger 10 | { 11 | void Log(LogEntry entry); 12 | } 13 | 14 | public enum LoggingEventType { Debug, Information, Warning, Error, Fatal }; 15 | 16 | // Immutable DTO that contains the log information. 17 | public class LogEntry 18 | { 19 | public readonly LoggingEventType Severity; 20 | public readonly string Message; 21 | public readonly Exception Exception; 22 | 23 | public LogEntry(LoggingEventType severity, string message, Exception exception = null) 24 | { 25 | if (message == null) throw new ArgumentNullException("message"); 26 | if (message == string.Empty) throw new ArgumentException("empty", "message"); 27 | 28 | this.Severity = severity; 29 | this.Message = message; 30 | this.Exception = exception; 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/Item.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | public partial class Item 10 | { 11 | [Key] 12 | [Column(Order = 0)] 13 | public Guid ID { get; set; } 14 | 15 | [Column(Order = 1)] 16 | [StringLength(256)] 17 | public string Name { get; set; } 18 | 19 | [Column(Order = 2)] 20 | public Guid TemplateID { get; set; } 21 | 22 | [Column(Order = 3)] 23 | public Guid MasterID { get; set; } 24 | 25 | [Column(Order = 4)] 26 | public Guid ParentID { get; set; } 27 | 28 | [Column(Order = 5)] 29 | public DateTime Created { get; set; } 30 | 31 | [Column(Order = 6)] 32 | public DateTime Updated { get; set; } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/UnversionedField.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | public partial class UnversionedField 10 | { 11 | [Key] 12 | [Column(Order = 0)] 13 | public Guid Id { get; set; } 14 | 15 | [Column(Order = 1)] 16 | public Guid ItemId { get; set; } 17 | 18 | [Column(Order = 2)] 19 | [StringLength(50)] 20 | public string Language { get; set; } 21 | 22 | [Column(Order = 3)] 23 | public Guid FieldId { get; set; } 24 | 25 | [Column(Order = 4)] 26 | [MaxLength] 27 | public string Value { get; set; } 28 | 29 | [Column(Order = 5)] 30 | public DateTime Created { get; set; } 31 | 32 | [Column(Order = 6)] 33 | public DateTime Updated { get; set; } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/SubmitActionConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class SubmitActionConstants 10 | { 11 | // Field Ids 12 | public const string SubmitActionFieldId = "{ABC57B6D-5542-4AB9-A889-106225A032E6}"; 13 | public const string ParametersFieldId = "{5C796924-3F06-4D1F-8510-8AD9A4244477}"; 14 | 15 | // Values 16 | public const string SubmitActionField_SaveActionValue = "{0C61EAB3-A61E-47B8-AE0B-B6EBA0D6EB1B}"; 17 | public const string SubmitActionField_RedirectToPageActionValue = "{3F3E2093-9DEA-4199-86CA-44FC69EF624D}"; 18 | public const string SubmitActionField_TriggerGoalActionValue = "{106587B9-1B9C-4DDB-AE96-BAC8416C21B5}"; 19 | public const string SubmitActionField_TriggerCampaignActivityActionValue = "{4A937D74-7986-4E19-9D8E-EC14675B17F0}"; 20 | public const string SubmitActionField_SendEmailActionValue = "{A082C3F9-D90F-4825-8A38-8D2BE7653FC0}"; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Forms/SitecoreForms.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Forms 2 | { 3 | using System; 4 | using System.Data.Entity; 5 | using System.ComponentModel.DataAnnotations.Schema; 6 | using System.Linq; 7 | 8 | public partial class SitecoreForms : DbContext 9 | { 10 | public SitecoreForms(string nameOrConnectionString) 11 | : base(nameOrConnectionString) 12 | { 13 | } 14 | 15 | public virtual DbSet FileStorages { get; set; } 16 | public virtual DbSet FieldDatas { get; set; } 17 | public virtual DbSet FormEntries { get; set; } 18 | 19 | protected override void OnModelCreating(DbModelBuilder modelBuilder) 20 | { 21 | modelBuilder.Entity() 22 | .Property(e => e.Created) 23 | .HasPrecision(3); 24 | 25 | modelBuilder.Entity() 26 | .Property(e => e.Created) 27 | .HasPrecision(3); 28 | 29 | modelBuilder.Entity() 30 | .HasMany(e => e.FieldDatas) 31 | .WithRequired(e => e.FormEntry) 32 | .WillCascadeOnDelete(false); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Alessandro Faniuolo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Email.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{84ABDA34-F9B1-4D3A-A69B-E28F39697069}", // Email 3 | "destTemplateId": "{886ADEC1-ABF8-40E1-9926-D9189C4E8E1B}", 4 | "destTemplateName": "Email", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{04C39CAC-8976-4910-BE0D-879ED3368429}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/DatePicker.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{09BF916E-79FB-4AE3-B799-659E63C75EA5}", // Date Picker 3 | "destTemplateId": "{5AC7621E-9F18-4569-BCEC-F5BF8BA1F4D7}", 4 | "destTemplateName": "Date", 5 | "baseTemplateMetadataFileName": "Date.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{38137D30-7B2A-47D5-BBD8-133252C01B28}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Password.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{1F09D460-200C-4C94-9673-488667FF75D1}", // Password 3 | "destTemplateId": "{05D71800-56BE-4A53-AFAB-3819DA817A4A}", 4 | "destTemplateName": "Password", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{668A1C37-9D6B-483B-B7C1-340C92D04BA4}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Telephone.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{F3A4D32A-0DD1-4613-8B0F-AC4C40E5D583}", // Telephone 3 | "destTemplateId": "{0908030B-4564-42EA-A6FA-C7A5A2D921A8}", 4 | "destTemplateName": "Telephone", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{DF74F55B-47E6-4D1C-92F8-B0D46A7B2704}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/RadioButtonList.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{0FAE4DE2-5C37-45A6-B474-9E3AB95FF452}", // Radio List 3 | "destTemplateId": "{5B672865-55D2-413E-B699-FDFC7E732CCF}", 4 | "destTemplateName": "RadioButtonList", 5 | "baseTemplateMetadataFileName": "List.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{EDBD38A8-1AE9-42EC-8CCD-F5B0E2998B4F}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/SingleLineText.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{6353E864-D3AE-4FF9-88DD-60B0F779A44A}", // Single-Line Text 3 | "destTemplateId": "{0908030B-4564-42EA-A6FA-C7A5A2D921A8}", 4 | "destTemplateName": "SingleLineText", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{4EE89EA7-CEFE-4C8E-8532-467EF64591FC}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/CheckboxList.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{E994EAE0-EDB0-4D89-B545-FEBEF07DD7CD}", // Checkbox List 3 | "destTemplateId": "{5B672865-55D2-413E-B699-FDFC7E732CCF}", 4 | "destTemplateName": "CheckboxList", 5 | "baseTemplateMetadataFileName": "List.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{D86A361A-D4FF-46B2-9E97-A37FC5B1FE1A}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Number.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{002E5FD5-8B12-4913-BA52-BCC5FEAD2785}", // Number 3 | "destTemplateId": "{E8D5A5A3-6430-4701-BAAD-1DB1947616CC}", 4 | "destTemplateName": "Number", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "dataValueType": "System.Double", 7 | "fields": { 8 | "newFields": [ 9 | { 10 | "fieldType": "shared", 11 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 12 | "value": "{5B153FC0-FC3F-474F-8CB8-233FB1BEF292}" 13 | } 14 | ], 15 | "convertedFields": [ 16 | { 17 | "fieldConverter": "", 18 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 19 | "destFields": [ 20 | 21 | ] 22 | }, 23 | { 24 | "fieldConverter": "", 25 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 26 | "destFields": [ 27 | 28 | ] 29 | } 30 | ] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Extensions.SitecoreFormsExtensions/Metadata/Custom/ReCaptcha.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{7FB270BE-FEFC-49C3-8CB4-947878C099E5}", // Captcha 3 | "destTemplateId": "{5A59C481-E3C3-4A03-A471-B5D1FB45181A}", // ReCaptcha 4 | "destTemplateName": "CaptchaField", 5 | "baseTemplateMetadataFileName": "Field.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{E383BDE2-BC88-4278-83EF-832A15C9E94A}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | 27 | ] 28 | } 29 | ] 30 | } 31 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Master/VersionedField.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Master 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | public partial class VersionedField 10 | { 11 | [Key] 12 | [Column(Order = 0)] 13 | public Guid Id { get; set; } 14 | 15 | [Column(Order = 1)] 16 | public Guid ItemId { get; set; } 17 | 18 | [Column(Order = 2)] 19 | [StringLength(50)] 20 | public string Language { get; set; } 21 | 22 | [Column(Order = 3)] 23 | [DatabaseGenerated(DatabaseGeneratedOption.None)] 24 | public int Version { get; set; } 25 | 26 | [Column(Order = 4)] 27 | public Guid FieldId { get; set; } 28 | 29 | [Column(Order = 5)] 30 | [MaxLength] 31 | public string Value { get; set; } 32 | 33 | [Column(Order = 6)] 34 | public DateTime Created { get; set; } 35 | 36 | [Column(Order = 7)] 37 | public DateTime Updated { get; set; } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/Forms/FormEntry.cs: -------------------------------------------------------------------------------- 1 | namespace WFFM.ConversionTool.Library.Database.Forms 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.ComponentModel.DataAnnotations; 6 | using System.ComponentModel.DataAnnotations.Schema; 7 | using System.Data.Entity.Spatial; 8 | 9 | [Table("sitecore_forms_storage.FormEntries")] 10 | public partial class FormEntry 11 | { 12 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 13 | public FormEntry() 14 | { 15 | FieldDatas = new HashSet(); 16 | } 17 | 18 | public Guid Id { get; set; } 19 | 20 | public Guid FormDefinitionId { get; set; } 21 | 22 | public Guid? ContactId { get; set; } 23 | 24 | public bool IsRedacted { get; set; } 25 | 26 | [Column(TypeName = "datetime2")] 27 | public DateTime Created { get; set; } 28 | 29 | [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 30 | public virtual ICollection FieldDatas { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Visualization/ProgressBar.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace WFFM.ConversionTool.Library.Visualization 4 | { 5 | public class ProgressBar 6 | { 7 | public static void DrawTextProgressBar(int progress, int total, string progressMessage) 8 | { 9 | //draw empty progress bar 10 | Console.CursorLeft = 2; 11 | Console.Write("["); //start 12 | Console.CursorLeft = 34; 13 | Console.Write("]"); //end 14 | Console.CursorLeft = 3; 15 | float onechunk = 30.0f / total; 16 | 17 | //draw filled part 18 | int position = 3; 19 | for (int i = 0; i < onechunk * progress; i++) 20 | { 21 | Console.BackgroundColor = ConsoleColor.Green; 22 | Console.CursorLeft = position++; 23 | Console.Write(" "); 24 | } 25 | 26 | //draw unfilled part 27 | for (int i = position; i <= 33; i++) 28 | { 29 | Console.BackgroundColor = ConsoleColor.Gray; 30 | Console.CursorLeft = position++; 31 | Console.Write(" "); 32 | } 33 | 34 | //draw totals 35 | Console.CursorLeft = 37; 36 | Console.BackgroundColor = ConsoleColor.Black; 37 | Console.Write($"{progress} of {total} {progressMessage} "); //blanks at the end remove any excess 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Folder.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{A87A00B1-E6DB-45AB-8B54-636FEC3B5523}", 3 | "destTemplateName": "Folder", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", 14 | "valueType": "System.Guid" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", 19 | "valueType": "System.DateTime" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", 24 | "value": "sitecore\\Admin" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", 29 | "valueType": "System.DateTime" 30 | } 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Reporting/ReportingRecord.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MongoDB.Driver.Core.WireProtocol.Messages; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Models.Reporting 10 | { 11 | public class ReportingRecord 12 | { 13 | public string ItemId { get; set; } 14 | public string ItemName { get; set; } 15 | public string ItemPath { get; set; } 16 | public int? ItemVersion { get; set; } 17 | public string ItemLanguage { get; set; } 18 | public string ItemTemplateId { get; set; } 19 | public string ItemTemplateName { get; set; } 20 | public string FormId { get; set; } 21 | public string FormName { get; set; } 22 | public string FieldId { get; set; } 23 | public string FieldName { get; set; } 24 | public string FieldType { get; set; } 25 | public string FieldValue { get; set; } 26 | public string FieldValueElementName { get; set; } 27 | public string FieldValueElementValue { get; set; } 28 | public string FieldValueReferencedItemId { get; set; } 29 | public string FieldValueReferencedItemName { get; set; } 30 | public string Message { get; set; } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/FileUpload.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{827BDF4A-D886-4B36-9D32-C443EBCA1806}", // File Upload 3 | "destTemplateId": "{17203DAA-0DED-4160-A23C-EC1114AB4FEF}", 4 | "destTemplateName": "File Upload", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "dataValueType": "System.Collections.Generic.List`1[Sitecore.ExperienceForms.Data.Entities.StoredFileInfo]", 7 | "dataValueConverter": "FileUploadConverter", 8 | "fields": { 9 | "newFields": [ 10 | { 11 | "fieldType": "shared", 12 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 13 | "value": "{7E9A0903-A52C-4843-BBE1-5B26BD162BED}" 14 | } 15 | ], 16 | "convertedFields": [ 17 | { 18 | "fieldConverter": "", 19 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 20 | "destFields": [ 21 | 22 | ] 23 | }, 24 | { 25 | "fieldConverter": "", 26 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 27 | "destFields": [ 28 | 29 | ] 30 | } 31 | ] 32 | } 33 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/ConnectionTester.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.SqlClient; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using MongoDB.Bson; 8 | using MongoDB.Driver; 9 | using WFFM.ConversionTool.Library.Database.MongoDB; 10 | 11 | namespace WFFM.ConversionTool.Library.Database 12 | { 13 | public static class ConnectionTester 14 | { 15 | public static bool IsServerConnected(string connectionString) 16 | { 17 | if (connectionString.ToLower().StartsWith("mongodb")) 18 | { 19 | try 20 | { 21 | var databaseName = MongoUrl.Create(connectionString).DatabaseName; 22 | var client = new MongoClient(connectionString).GetDatabase(databaseName); 23 | var collection = client.GetCollection("FormData").CountDocuments(new BsonDocument()); 24 | return true; 25 | } 26 | catch (Exception ex) 27 | { 28 | return false; 29 | } 30 | } 31 | else 32 | { 33 | using (SqlConnection connection = new SqlConnection(connectionString)) 34 | { 35 | try 36 | { 37 | connection.Open(); 38 | return true; 39 | } 40 | catch (SqlException) 41 | { 42 | return false; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Database/MongoDB/MongoAnalytics.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using MongoDB.Bson; 7 | using MongoDB.Bson.Serialization.Attributes; 8 | using MongoDB.Driver; 9 | 10 | namespace WFFM.ConversionTool.Library.Database.MongoDB 11 | { 12 | public class MongoAnalytics 13 | { 14 | private IMongoClient _client; 15 | private IMongoDatabase _database; 16 | private IMongoCollection _formDataCollection; 17 | 18 | public MongoAnalytics(string connectionString) 19 | { 20 | 21 | MongoDefaults.GuidRepresentation = GuidRepresentation.CSharpLegacy; 22 | var _databaseName = MongoUrl.Create(connectionString).DatabaseName; 23 | var _client = new MongoClient(connectionString).GetDatabase(_databaseName); 24 | 25 | _formDataCollection = _client.GetCollection("FormData"); 26 | } 27 | 28 | public List GetFormDataByFormItemId(Guid formItemId) 29 | { 30 | var result = _formDataCollection.Find(d => d.FormId == formItemId).ToList(); 31 | return result; 32 | } 33 | 34 | public FormData GetFormDataByFormRecordId(Guid formRecordId) 35 | { 36 | var result = _formDataCollection.Find(d => d.Id == formRecordId).FirstOrDefault(); 37 | return result; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Logging/Log4NetAdapter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using log4net; 8 | 9 | namespace WFFM.ConversionTool.Library.Logging 10 | { 11 | public class Log4NetAdapter : ILogger 12 | { 13 | private readonly log4net.ILog m_Adaptee; 14 | 15 | public Log4NetAdapter() 16 | { 17 | log4net.GlobalContext.Properties["LogName"] = $"log.{DateTime.Now.ToString("yyyyMMdd.hhmmss")}.txt"; 18 | 19 | m_Adaptee = LogManager.GetLogger(typeof(T)); 20 | 21 | log4net.Config.XmlConfigurator.Configure(); 22 | Trace.Listeners.Add(new Log4NetTraceListener()); 23 | } 24 | 25 | public void Log(LogEntry entry) 26 | { 27 | //Here invoke m_Adaptee 28 | if (entry.Severity == LoggingEventType.Debug) 29 | m_Adaptee.Debug(entry.Message, entry.Exception); 30 | else if (entry.Severity == LoggingEventType.Information) 31 | m_Adaptee.Info(entry.Message, entry.Exception); 32 | else if (entry.Severity == LoggingEventType.Warning) 33 | m_Adaptee.Warn(entry.Message, entry.Exception); 34 | else if (entry.Severity == LoggingEventType.Error) 35 | m_Adaptee.Error(entry.Message, entry.Exception); 36 | else 37 | m_Adaptee.Fatal(entry.Message, entry.Exception); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Repositories/SitecoreFormsDbRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Entity.Migrations; 4 | using System.Linq; 5 | using WFFM.ConversionTool.Library.Database.Forms; 6 | 7 | namespace WFFM.ConversionTool.Library.Repositories 8 | { 9 | public class SitecoreFormsDbRepository : ISitecoreFormsDbRepository 10 | { 11 | private SitecoreForms _sitecoreFormsDb; 12 | 13 | public SitecoreFormsDbRepository(SitecoreForms sitecoreFormsDb) 14 | { 15 | _sitecoreFormsDb = sitecoreFormsDb; 16 | } 17 | 18 | public void CreateOrUpdateFormData(FormEntry formEntry) 19 | { 20 | _sitecoreFormsDb.FormEntries.AddOrUpdate(formEntry); 21 | _sitecoreFormsDb.SaveChanges(); 22 | 23 | foreach (FieldData fieldData in formEntry.FieldDatas) 24 | { 25 | _sitecoreFormsDb.FieldDatas.AddOrUpdate(fieldData); 26 | } 27 | _sitecoreFormsDb.SaveChanges(); 28 | } 29 | 30 | public void DeleteFieldDataByFormRecordId(Guid formRecordId) 31 | { 32 | _sitecoreFormsDb.FieldDatas.RemoveRange(_sitecoreFormsDb.FieldDatas.Where(f => f.FormEntryId == formRecordId)); 33 | } 34 | 35 | public void CreateOrUpdateFileStorageFormRecord(FileStorage fileStorage) 36 | { 37 | _sitecoreFormsDb.FileStorages.AddOrUpdate(fileStorage); 38 | _sitecoreFormsDb.SaveChanges(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/MultipleLineText.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{42DB4C51-5A19-4BD3-9632-CB488DD63849}", // Multiple-Line Text 3 | "destTemplateId": "{D8386D04-C1E3-4CD3-9227-9E9F86EF3C88}", 4 | "destTemplateName": "MultipleLineText", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{A296A1C1-0DA0-4493-A92E-B8191F43AEC6}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | { 20 | "sourceElementName": "Rows", 21 | "destFieldId": "{E43E4E5F-6B45-4E3B-8D85-85AB87D2CC12}", // Rows 22 | "fieldConverter": "" 23 | } 24 | ] 25 | }, 26 | { 27 | "fieldConverter": "", 28 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 29 | "destFields": [ 30 | 31 | ] 32 | } 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/DropdownList.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{C6D97C39-23B5-4B7E-AFC7-9F41795533C6}", // Drop List 3 | "destTemplateId": "{9121D435-48B8-4649-9D13-03D680474FAD}", 4 | "destTemplateName": "DropdownList", 5 | "baseTemplateMetadataFileName": "List.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{E0CFADEE-1AC0-471D-A820-2E70D1547B4B}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | { 20 | "sourceElementName": "EmptyChoice", 21 | "destFieldId": "{6BF5048D-FBBD-4839-9F18-4412D4E11834}", // Show Empty Value 22 | "fieldConverter": "YesNoConverter" 23 | } 24 | ] 25 | }, 26 | { 27 | "fieldConverter": "", 28 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 29 | "destFields": [ 30 | 31 | ] 32 | } 33 | ] 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Checkbox.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{E079EE36-8620-4D3C-B9BF-010D7A58311F}", // Checkbox 3 | "destTemplateId": "{2F07293C-077F-456C-B715-FDB791ACB367}", 4 | "destTemplateName": "Checkbox", 5 | "baseTemplateMetadataFileName": "Field.json", 6 | "dataValueType": "System.Boolean", 7 | "dataValueConverter": "BooleanConverter", 8 | "fields": { 9 | "newFields": [ 10 | { 11 | "fieldType": "shared", 12 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 13 | "value": "{4DA85E8A-3B48-4BC6-9565-8C1F5F36DD1B}" 14 | } 15 | ], 16 | "convertedFields": [ 17 | { 18 | "fieldConverter": "", 19 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 20 | "destFields": [ 21 | { 22 | "sourceElementName": "Checked", 23 | "destFieldId": "{3C05A626-A3B1-4CBC-BF67-198537A13E20}", // Default Value 24 | "fieldConverter": "YesNoConverter" 25 | } 26 | ] 27 | }, 28 | { 29 | "fieldConverter": "", 30 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 31 | "destFields": [ 32 | 33 | ] 34 | } 35 | ] 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Validators/AppSettingsValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json.Linq; 8 | using Newtonsoft.Json.Schema; 9 | 10 | namespace WFFM.ConversionTool.Library.Validators 11 | { 12 | public class AppSettingsValidator : IValidator 13 | { 14 | private readonly string AppSettingsFilePath = "AppSettings.json"; 15 | 16 | public bool Validate() 17 | { 18 | bool isValid = true; 19 | 20 | // Load Schema 21 | JsonSchema appSettingsSchema = LoadAppSettingsSchema(); 22 | 23 | // Validate 24 | // Read json file 25 | var appSettingsFileContent = System.IO.File.ReadAllText(AppSettingsFilePath); 26 | var appSettingsFileJson = JObject.Parse(appSettingsFileContent); 27 | 28 | // Break with message in Console if a json file is not valid 29 | if (!appSettingsFileJson.IsValid(appSettingsSchema)) 30 | { 31 | Console.WriteLine(); 32 | Console.WriteLine(" Execution aborted!"); 33 | Console.WriteLine(string.Format(" The following file doesn't contain a valid JSON object: {0}", AppSettingsFilePath)); 34 | Console.WriteLine(); 35 | return false; 36 | } 37 | 38 | return isValid; 39 | } 40 | 41 | private JsonSchema LoadAppSettingsSchema() 42 | { 43 | var appSettingsSchemaFile = File.ReadAllText(@"Schemas\appsettings-schema.json"); 44 | return JsonSchema.Parse(appSettingsSchemaFile); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Metadata/AppSettings.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using Newtonsoft.Json; 7 | 8 | namespace WFFM.ConversionTool.Library.Models.Metadata 9 | { 10 | public class AppSettings 11 | { 12 | public Dictionary itemReferences { get; set; } 13 | public List converters { get; set; } 14 | public List submitActions { get; set; } 15 | 16 | public bool enableOnlyAnalysisByDefault { get; set; } 17 | public string metadataFolderRelativePath { get; set; } 18 | public string invalidItemNameChars { get; set; } 19 | 20 | public bool enableReferencedItemCheck { get; set; } 21 | public string formsDataProvider { get; set; } 22 | public bool analysis_ExcludeBaseStandardFields { get; set; } 23 | public bool excludeSampleWffmForms { get; set; } 24 | public List includeOnlyFormIds { get; set; } 25 | public List excludeFormIds { get; set; } 26 | 27 | public Dictionary extensions { get; set; } 28 | 29 | public class Converter 30 | { 31 | public string name { get; set; } 32 | public string converterType { get; set; } 33 | } 34 | 35 | public class SubmitAction 36 | { 37 | public Guid sourceSaveActionId { get; set; } 38 | public string destSubmitActionItemName { get; set; } 39 | public string destSubmitActionFieldValue { get; set; } 40 | public string destParametersConverterType { get; set; } 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WFFM.ConversionTool.Library")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WFFM.ConversionTool.Library")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("670ad498-f9f3-45bc-81a5-4c5841249298")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.6.0.0")] 36 | [assembly: AssemblyFileVersion("1.6.0.0")] 37 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/FieldProvider.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Helpers; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Providers 10 | { 11 | public class FieldProvider : IFieldProvider 12 | { 13 | public Dictionary, string> GetFieldValues(SCItem sourceItem, Guid sourceFieldId, string defaultValue, bool stripHtml = false) 14 | { 15 | var values = new Dictionary, string>(); 16 | var fieldType = sourceItem.Fields.FirstOrDefault(f => f.FieldId == sourceFieldId)?.Type; 17 | IEnumerable> langVersions = sourceItem.Fields.Where(f => f.Version != null && f.Language != null).Select(f => new Tuple(f.Language, (int)f.Version)).Distinct(); 18 | var languages = sourceItem.Fields.Where(f => f.Language != null).Select(f => f.Language).Distinct(); 19 | foreach (var langVersion in langVersions) 20 | { 21 | var value = sourceItem.Fields.FirstOrDefault(f => 22 | f.FieldId == sourceFieldId && f.Language == langVersion.Item1 && f.Version == langVersion.Item2)?.Value; 23 | 24 | if (fieldType == FieldType.Unversioned) 25 | { 26 | value = sourceItem.Fields.FirstOrDefault(f => 27 | f.FieldId == sourceFieldId && f.Language == langVersion.Item1)?.Value; 28 | } 29 | 30 | if (stripHtml) 31 | { 32 | value = XmlHelper.StripHtml(value); 33 | } 34 | values.Add(langVersion, value ?? defaultValue); 35 | } 36 | 37 | return values; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Extensions.SitecoreFormsExtensions/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WFFM.ConversionTool.Extensions.SitecoreFormsExtensions")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WFFM.ConversionTool.Extensions.SitecoreFormsExtensions")] 13 | [assembly: AssemblyCopyright("Copyright © 2019")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b0f28bbf-bcdf-491b-a6d3-406f7b042c24")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.6.0.0")] 36 | [assembly: AssemblyFileVersion("1.6.0.0")] 37 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/ListBox.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{CDD533E2-918A-4BE3-A12F-83A8580363F7}", // List Box 3 | "destTemplateId": "{81FE389A-FDC7-4ECA-A5A9-4BE3ACA0C69A}", 4 | "destTemplateName": "ListBox", 5 | "baseTemplateMetadataFileName": "List.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{222A2121-D370-4C6F-80A3-03C930B718BF}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | { 20 | "sourceElementName": "SelectionMode", 21 | "destFieldId": "{F1299F31-B054-40AF-B5FB-6F16692CCBDF}", // Multiple Selection 22 | "fieldConverter": "SelectionModeConverter" 23 | }, 24 | { 25 | "sourceElementName": "Rows", 26 | "destFieldId": "{3F67BE6A-F3F0-41C5-B379-C6AF29685666}", // Rows 27 | "fieldConverter": "" 28 | } 29 | ] 30 | }, 31 | { 32 | "fieldConverter": "", 33 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 34 | "destFields": [ 35 | 36 | ] 37 | } 38 | ] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("WFFM.ConversionTool")] 9 | [assembly: AssemblyDescription("Console app to convert and migrate Sitecore WFFM forms items and data to Sitecore Forms")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("WFFM.ConversionTool")] 13 | [assembly: AssemblyCopyright("Copyright © 2019 Alessandro Faniuolo")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("49cd87dd-7950-4296-87b0-d5495d7a3a5a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.6.0.0")] 36 | [assembly: AssemblyFileVersion("1.6.0.0")] 37 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Form.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceTemplateId": "{FFB1DA32-2764-47DB-83B0-95B843546A7E}", 3 | "sourceTemplateName": "Form", 4 | "destTemplateId": "{6ABEE1F2-4AB4-47F0-AD8B-BDB36F37F64C}", 5 | "destTemplateName": "Form", 6 | "baseTemplateMetadataFileName": "BaseTemplate.json", 7 | "fields": { 8 | "newFields": [ 9 | { 10 | "fieldType": "shared", 11 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", 12 | "value": "{3A4DF9C0-7C82-4415-90C3-25440257756D}" 13 | }, 14 | { 15 | "fieldType": "shared", 16 | "destFieldId": "{FCE03B41-4CBB-4F7F-920F-FF04F12FA896}", 17 | "value": "jquery-3.4.1.min.js|jquery.validate.min.js|jquery.validate.unobtrusive.min.js|jquery.unobtrusive-ajax.min.js|form.validate.js|form.tracking.js|form.conditions.js" 18 | }, 19 | { 20 | "fieldType": "shared", 21 | "destFieldId": "{9EB86F19-2E5D-48DB-9795-0EE4868EFF11}", 22 | "value": "1" 23 | } 24 | ], 25 | "convertedFields": [ 26 | { 27 | "fieldConverter": "TrackingConverter", 28 | "sourceFieldId": "{B0A67B2A-8B07-4E0B-8809-69F751709806}", // Tracking 29 | "destFieldId": "{D99833EA-238A-4505-90EF-C69BF3EBA946}" 30 | }, 31 | { 32 | "fieldConverter": "", 33 | "sourceFieldId": "{0F110210-9EA9-47C6-93AF-7DCE616C3602}", // Custom CSS Class 34 | "destFieldId": "{7ABAA3F6-6EC0-4B65-A463-7919BFAE55AA}" // CSS Class 35 | } 36 | ] 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Validators/DbConnectionStringValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Database; 7 | using WFFM.ConversionTool.Library.Models.Metadata; 8 | 9 | namespace WFFM.ConversionTool.Library.Validators 10 | { 11 | public class DbConnectionStringValidator : IValidator 12 | { 13 | private AppSettings _appSettings; 14 | 15 | public DbConnectionStringValidator(AppSettings appSettings) 16 | { 17 | _appSettings = appSettings; 18 | } 19 | 20 | public bool Validate() 21 | { 22 | bool isSqlFormsDataProvider = string.Equals(_appSettings.formsDataProvider, "sqlFormsDataProvider", StringComparison.InvariantCultureIgnoreCase); 23 | 24 | return ValidateConnectionString("SitecoreForms") && ValidateConnectionString("SourceMasterDb") && ValidateConnectionString("DestMasterDb") && 25 | (isSqlFormsDataProvider ? ValidateConnectionString("WFFM") : ValidateConnectionString("mongodb_analytics")); 26 | } 27 | 28 | private bool ValidateConnectionString(string connectionStringName) 29 | { 30 | var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings[connectionStringName].ConnectionString; 31 | 32 | var connectionIsValid = string.IsNullOrEmpty(connectionString) || ConnectionTester.IsServerConnected(connectionString); 33 | if (!connectionIsValid) 34 | { 35 | Console.WriteLine(); 36 | Console.WriteLine(" Execution aborted!"); 37 | Console.WriteLine($" The {connectionStringName} connection string is not valid."); 38 | Console.WriteLine(); 39 | } 40 | 41 | return connectionIsValid; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/EmailAddress.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{DD91460C-D205-4D4B-8F87-D7980C8BA9F6}", 3 | "destTemplateName": "Email Address", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", // __Updated by 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", // __Created by 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", // __Revision 19 | "valueType": "System.Guid" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", // __Created 24 | "valueType": "System.DateTime" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", // __Owner 29 | "value": "sitecore\\Admin" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", // __Updated 34 | "valueType": "System.DateTime" 35 | }, 36 | { 37 | "fieldType": "versioned", 38 | "destFieldId": "{49DC3FF7-C17D-4574-B88E-2418DCE1315F}", // Value 39 | "valueType": "System.String" 40 | } 41 | ] 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Input.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{0908030B-4564-42EA-A6FA-C7A5A2D921A8}", 3 | "destTemplateName": "Input", 4 | "baseTemplateMetadataFileName": "Field.json", 5 | "fields": { 6 | "convertedFields": [ 7 | { 8 | "fieldConverter": "", 9 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 10 | "destFields": [ 11 | { 12 | "sourceElementName": "MinLength", 13 | "destFieldId": "{9F7DA002-7B86-436B-8DDA-7EFE5837B88E}", // Min Length 14 | "fieldConverter": "" 15 | }, 16 | { 17 | "sourceElementName": "MaxLength", 18 | "destFieldId": "{71061C01-A495-4BF3-A52C-D378346BFAE2}", // Max Length 19 | "fieldConverter": "" 20 | } 21 | ] 22 | }, 23 | { 24 | "fieldConverter": "", 25 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 26 | "destFields": [ 27 | { 28 | "sourceElementName": "Text", 29 | "destFieldId": "{B775BCA9-2605-4D60-B367-A0C354BE2504}", // Default Value 30 | "fieldConverter": "" 31 | }, 32 | { 33 | "sourceElementName": "Information", 34 | "destFieldId": "{A6972F08-CBB5-4830-A8C9-8A0AE34650D1}", // Placeholder Text 35 | "fieldConverter": "" 36 | } 37 | ] 38 | } 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/SelectedValueConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Helpers; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 10 | { 11 | public class SelectedValueConverter : BaseFieldConverter 12 | { 13 | public override SCField ConvertValueElement(SCField scField, Guid destFieldId, string elementValue, List destItems = null) 14 | { 15 | if (destItems == null || !destItems.Any()) 16 | { 17 | elementValue = string.Empty; 18 | return base.ConvertValueElement(scField, destFieldId, elementValue, destItems); 19 | } 20 | 21 | var itemElements = XmlHelper.GetXmlElementNodeList(elementValue, "item"); 22 | if (itemElements == null || itemElements.Count == 0) 23 | { 24 | elementValue = string.Empty; 25 | return base.ConvertValueElement(scField, destFieldId, elementValue, destItems); 26 | } 27 | 28 | var firstSelectedItemValue = itemElements.Item(0)?.InnerXml ?? string.Empty; 29 | 30 | var selectedItemId = destItems.FirstOrDefault(i => 31 | i.TemplateID == new Guid("{B3BDFE59-6667-4432-B261-05D0E3F7FDF6}") // Item is Extendend List Item 32 | && string.Equals( 33 | i.Fields.FirstOrDefault(f => f.FieldId == new Guid("{3A07C171-9BCA-464D-8670-C5703C6D3F11}"))?.Value, // Select Field Value 34 | firstSelectedItemValue, StringComparison.InvariantCultureIgnoreCase))?.ID.ToString("B").ToUpper() ?? 35 | string.Empty; 36 | 37 | return CreateFieldFromElement(scField, destFieldId, selectedItemId); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Providers/FormsData/MongoDbDataReader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using WFFM.ConversionTool.Library.Database.MongoDB; 4 | using FieldData = WFFM.ConversionTool.Library.Database.WFFM.FieldData; 5 | using FormData = WFFM.ConversionTool.Library.Database.WFFM.FormData; 6 | 7 | namespace WFFM.ConversionTool.Library.Providers.FormsData 8 | { 9 | public class MongoDbDataProvider : IDataProvider 10 | { 11 | private MongoAnalytics _mongoAnalytics; 12 | 13 | public MongoDbDataProvider(MongoAnalytics mongoAnalytics) 14 | { 15 | _mongoAnalytics = mongoAnalytics; 16 | } 17 | 18 | public List GetFormDataRecords(Guid formItemId) 19 | { 20 | var mongoDbFormData = _mongoAnalytics.GetFormDataByFormItemId(formItemId); 21 | var formData = new List(); 22 | 23 | foreach (var data in mongoDbFormData) 24 | { 25 | formData.Add(new FormData() 26 | { 27 | Id = data.Id, 28 | ContactId = data.ContactId, 29 | Data = string.Empty, 30 | FormItemId = data.FormId, 31 | InteractionId = data.InteractionId, 32 | TimeStamp = data.Timestamp 33 | }); 34 | } 35 | 36 | return formData; 37 | } 38 | 39 | public List GetFieldDataRecords(Guid formRecordId) 40 | { 41 | var mongoDbFormData = _mongoAnalytics.GetFormDataByFormRecordId(formRecordId); 42 | var fieldDatas = new List(); 43 | 44 | foreach (var fieldData in mongoDbFormData.FieldDatas) 45 | { 46 | fieldDatas.Add(new FieldData() 47 | { 48 | Id = Guid.NewGuid(), 49 | FieldItemId = fieldData.FieldId, 50 | Data = fieldData.Data, 51 | Value = fieldData.Value, 52 | FieldName = fieldData.FieldName, 53 | FormId = formRecordId 54 | }); 55 | } 56 | 57 | return fieldDatas; 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldValueConverters/FileUploadConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using WFFM.ConversionTool.Library.Logging; 8 | using WFFM.ConversionTool.Library.Models.Metadata; 9 | using WFFM.ConversionTool.Library.Repositories; 10 | 11 | namespace WFFM.ConversionTool.Library.Converters.FieldValueConverters 12 | { 13 | public class FileUploadConverter : BaseFieldConverter 14 | { 15 | private ISourceMasterRepository _sourceMasterRepository; 16 | private AppSettings _appSettings; 17 | private ILogger _logger; 18 | 19 | public FileUploadConverter(ISourceMasterRepository sourceMasterRepository, AppSettings appSettings, ILogger logger) 20 | { 21 | _sourceMasterRepository = sourceMasterRepository; 22 | _appSettings = appSettings; 23 | _logger = logger; 24 | } 25 | 26 | public override string ConvertValue(string sourceValue) 27 | { 28 | // Parse the value to get the media item ID 29 | // Example: sitecore://master/{A1207618-AFC1-465A-A45A-5F1C47A59B34}?lang=en&ver=1 30 | var mediaItemRegexMatch = Regex.Match(sourceValue, @"sitecore:\/\/master\/(.*)\?lang=(.*)&ver=1"); 31 | var mediaItemId = mediaItemRegexMatch.Groups[1].Value; 32 | var mediaItemLanguage = mediaItemRegexMatch.Groups[2].Value; 33 | 34 | if (string.IsNullOrEmpty(mediaItemId) || !Guid.TryParse(mediaItemId, out var mediaItemGuid)) 35 | { 36 | return sourceValue; 37 | } 38 | 39 | // Get the media item from source master db and map fields 40 | var mediaItem = _sourceMasterRepository.GetSitecoreItem(mediaItemGuid); 41 | 42 | if (string.IsNullOrEmpty(mediaItem.Name)) return sourceValue; 43 | 44 | return mediaItemGuid.ToString("D"); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.sln.docstates 8 | .vs 9 | 10 | # Build results 11 | [Dd]ebug/ 12 | [Dd]ebugPublic/ 13 | [Rr]elease/ 14 | [Rr]eleases/ 15 | x64/ 16 | x86/ 17 | build/ 18 | bld/ 19 | [Bb]in/ 20 | [Oo]bj/ 21 | 22 | # Roslyn cache directories 23 | *.ide/ 24 | 25 | # MSTest test Results 26 | [Tt]est[Rr]esult*/ 27 | [Bb]uild[Ll]og.* 28 | 29 | #NUNIT 30 | *.VisualState.xml 31 | TestResult.xml 32 | 33 | # Visual Studio profiler 34 | *.psess 35 | *.vsp 36 | *.vspx 37 | 38 | # ReSharper is a .NET coding add-in 39 | _ReSharper*/ 40 | *.[Rr]e[Ss]harper 41 | *.DotSettings.user 42 | 43 | # DotCover is a Code Coverage Tool 44 | *.dotCover 45 | 46 | # NCrunch 47 | _NCrunch_* 48 | .*crunch*.local.xml 49 | 50 | # NuGet Packages 51 | *.nupkg 52 | # The packages folder can be ignored because of Package Restore 53 | **/packages/* 54 | # except build/, which is used as an MSBuild target. 55 | !**/packages/build/ 56 | # If using the old MSBuild-Integrated Package Restore, uncomment this: 57 | #!**/packages/repositories.config 58 | 59 | # Others 60 | *.Cache 61 | ClientBin/ 62 | [Ss]tyle[Cc]op.* 63 | ~$* 64 | *~ 65 | *.dbmdl 66 | *.dbproj.schemaview 67 | *.pfx 68 | *.publishsettings 69 | node_modules/ 70 | 71 | # Backup & report files from converting an old project file 72 | # to a newer Visual Studio version. Backup files are not needed, 73 | # because we have git ;-) 74 | _UpgradeReport_Files/ 75 | Backup*/ 76 | UpgradeLog*.XML 77 | UpgradeLog*.htm 78 | 79 | # SQL Server files 80 | *.mdf 81 | *.ldf 82 | 83 | #config and build 84 | config/env/local.properties 85 | !tools/**/bin 86 | 87 | .DS_Store 88 | **/.DS_Store 89 | 90 | .sonar/* 91 | sonar-project.properties 92 | 93 | 94 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Validators/MetadataValidator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using Newtonsoft.Json.Linq; 9 | using Newtonsoft.Json.Schema; 10 | using WFFM.ConversionTool.Library.Models.Metadata; 11 | using WFFM.ConversionTool.Library.Providers; 12 | 13 | namespace WFFM.ConversionTool.Library.Validators 14 | { 15 | public class MetadataValidator : IValidator 16 | { 17 | private IMetadataProvider _metadataProvider; 18 | 19 | public MetadataValidator(IMetadataProvider metadataProvider) 20 | { 21 | _metadataProvider = metadataProvider; 22 | } 23 | 24 | public bool Validate() 25 | { 26 | bool isValid = true; 27 | 28 | // Load Schema 29 | JsonSchema metadataSchema = LoadMetadataSchema(); 30 | 31 | // Load all metadata files 32 | var metadataFiles = _metadataProvider.GetAllMetadataFiles(); 33 | 34 | // Validate each file 35 | foreach (string metadataFile in metadataFiles) 36 | { 37 | // Read json file 38 | var metadataFileContent = System.IO.File.ReadAllText(metadataFile); 39 | var metadataFileJson = JObject.Parse(metadataFileContent); 40 | 41 | // Break with message in Console if a json file is not valid 42 | if (!metadataFileJson.IsValid(metadataSchema)) 43 | { 44 | Console.WriteLine(); 45 | Console.WriteLine(" Execution aborted!"); 46 | Console.WriteLine(string.Format(" The following metadata file doesn't contain a valid JSON object: {0}", metadataFile)); 47 | Console.WriteLine(); 48 | return false; 49 | } 50 | } 51 | 52 | return isValid; 53 | } 54 | 55 | private JsonSchema LoadMetadataSchema() 56 | { 57 | var metadataSchemaFile = File.ReadAllText(@"Schemas\metadata-schema.json"); 58 | return JsonSchema.Parse(metadataSchemaFile); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/ExtendedListItem.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{B3BDFE59-6667-4432-B261-05D0E3F7FDF6}", 3 | "destTemplateName": "ExtendedListItem", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", // __Updated by 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", // __Created by 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", // __Revision 19 | "valueType": "System.Guid" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", // __Created 24 | "valueType": "System.DateTime" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", // __Owner 29 | "value": "sitecore\\Admin" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", // __Updated 34 | "valueType": "System.DateTime" 35 | }, 36 | { 37 | "fieldType": "unversioned", 38 | "destFieldId": "{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}", // __Display name 39 | "valueType": "System.String" 40 | }, 41 | { 42 | "fieldType": "shared", 43 | "destFieldId": "{3A07C171-9BCA-464D-8670-C5703C6D3F11}", // Value 44 | "valueType": "System.String" 45 | } 46 | ] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Date.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{95DD3FCF-2E03-4064-9968-614D1452F20B}", // Date 3 | "destTemplateId": "{5AC7621E-9F18-4569-BCEC-F5BF8BA1F4D7}", 4 | "destTemplateName": "Date", 5 | "baseTemplateMetadataFileName": "Field.json", 6 | "dataValueType": "System.DateTime", 7 | "dataValueConverter": "DateValueConverter", 8 | "fields": { 9 | "newFields": [ 10 | { 11 | "fieldType": "shared", 12 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 13 | "value": "{38137D30-7B2A-47D5-BBD8-133252C01B28}" 14 | } 15 | ], 16 | "convertedFields": [ 17 | { 18 | "fieldConverter": "", 19 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 20 | "destFields": [ 21 | { 22 | "sourceElementName": "StartDate", 23 | "destFieldId": "{CC82B5D9-B130-435C-8992-74E798966527}", // Min 24 | "fieldConverter": "DateConverter" 25 | }, 26 | { 27 | "sourceElementName": "EndDate", 28 | "destFieldId": "{E47830D7-EB85-46FF-AA95-5A2914D12E9A}", // Max 29 | "fieldConverter": "DateConverter" 30 | }, 31 | { 32 | "sourceElementName": "SelectedDate", 33 | "destFieldId": "{6D66CA46-0489-4129-BA2C-CDE3E935DB7C}", // Default Value 34 | "fieldConverter": "DateConverter" 35 | } 36 | ] 37 | }, 38 | { 39 | "fieldConverter": "", 40 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 41 | "destFields": [ 42 | 43 | ] 44 | } 45 | ] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/SubmitActionDefinition.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{05FE45D4-B9C7-40DE-B767-7C5ABE7119F9}", 3 | "destTemplateName": "SubmitActionDefinition", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", 19 | "valueType": "System.Guid" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", 24 | "valueType": "System.DateTime" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", 29 | "value": "sitecore\\Admin" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", 34 | "valueType": "System.DateTime" 35 | }, 36 | { 37 | "fieldType": "shared", 38 | "destFieldId": "{ABC57B6D-5542-4AB9-A889-106225A032E6}", // Submit Action 39 | "value": "" 40 | }, 41 | { 42 | "fieldType": "shared", 43 | "destFieldId": "{5C796924-3F06-4D1F-8510-8AD9A4244477}", // Parameters 44 | "value": "" 45 | }, 46 | { 47 | "fieldType": "shared", 48 | "destFieldId": "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}", // __Sort Order 49 | "value": "0" 50 | } 51 | ] 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Constants/FormConstants.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace WFFM.ConversionTool.Library.Constants 8 | { 9 | public class FormConstants 10 | { 11 | // Field Ids 12 | public const string FormShowTitleFieldId = "{A42052F7-6C18-424A-A2A1-7A72054CB1A6}"; 13 | public const string FormTitleFieldId = "{86D6A401-5A20-49C9-A2F8-0312398EE946}"; 14 | public const string FormTitleTagFieldId = "{6739FA82-A9B4-40F1-AEFE-3D67AE3E8DFC}"; 15 | 16 | public const string FormShowIntroductionFieldId = "{46FB324A-9741-43BD-A0C9-5081A39D40AA}"; 17 | public const string FormIntroductionFieldId = "{0F2414BD-A95D-419C-A238-A6637A3FAB76}"; 18 | 19 | public const string FormShowFooterFieldId = "{FAEACD39-B059-4F46-BEC4-74BA468A97B8}"; 20 | public const string FormFooterFieldId = "{95968A5A-DB52-4F50-B471-C6C7DA81F7E8}"; 21 | 22 | public const string FormTrackingFieldId = "{B0A67B2A-8B07-4E0B-8809-69F751709806}"; 23 | 24 | public const string FormSaveToDatabaseFieldId = "{5B891B54-4FCE-489E-A7E6-841D92E9859A}"; 25 | public const string FormSubmitModeFieldId = "{D755DE87-9C62-4EB3-83DC-2293784A3A3F}"; 26 | public const string FormSuccessPageFieldId = "{9C4C1994-5140-49D3-BAD7-DB997816F816}"; 27 | public const string FormSaveActionFieldId = "{A7F779B9-5FCF-45CC-866B-7C973F5C4FAC}"; 28 | public const string FormSuccessMessageFieldId = "{4E2DC894-59A2-49BB-A49C-562F611169A2}"; 29 | public const string FormSubmitNameFieldId = "{B71296B6-32B9-4703-A8CB-FB7437271103}"; 30 | 31 | // Values 32 | public const string FormTitleTagStandardValue = "H1"; 33 | public const string FormSubmitModeField_RedirectModeValue = "{F4D50806-6B89-4F2D-89FE-F77FC0A07D48}"; 34 | public const string FormSubmitModeField_ShowMessageValue = "{3B8369A0-CC1A-4E9A-A3DB-7B086379C53B}"; 35 | public const string FormSaveAction_RegisterCampaignValue = "{AD26FE98-EED1-45C8-95AE-F2714EE33C62}"; 36 | public const string FormSaveAction_SaveToDatabaseValue = "{F03608CC-559B-451E-BC5B-6A7ADFF32C94}"; 37 | public const string FormSaveAction_SendEmailValue = "{D4502A11-9417-4479-9F2A-485F45D2E2D0}"; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/BaseTemplate.json: -------------------------------------------------------------------------------- 1 | { 2 | "fields": { 3 | "existingFields": [ 4 | { 5 | "fieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}" // __Created by 6 | }, 7 | { 8 | "fieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}" // __Updated by 9 | }, 10 | { 11 | "fieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}" // __Revision 12 | }, 13 | { 14 | "fieldId": "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}" // __Sortorder 15 | }, 16 | { 17 | "fieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}" // __Created 18 | }, 19 | { 20 | "fieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}" // __Owner 21 | }, 22 | { 23 | "fieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}" // __Updated 24 | }, 25 | { 26 | "fieldId": "{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}" // __Display name 27 | }, 28 | { 29 | "fieldId": "{C8F93AFE-BFD4-4E8F-9C61-152559854661}" // __Valid from 30 | }, 31 | { 32 | "fieldId": "{4C346442-E859-4EFD-89B2-44AEDF467D21}" // __Valid to 33 | }, 34 | { 35 | "fieldId": "{B8F42732-9CB8-478D-AE95-07E25345FB0F}" // __Hide version 36 | }, 37 | { 38 | "fieldId": "{86FE4F77-4D9A-4EC3-9ED9-263D03BD1965}" // __Publish 39 | }, 40 | { 41 | "fieldId": "{7EAD6FD6-6CF1-4ACA-AC6B-B200E7BAFE88}" // __Unpublish 42 | }, 43 | { 44 | "fieldId": "{74484BDF-7C86-463C-B49F-7B73B9AFC965}" // __Publishing groups 45 | }, 46 | { 47 | "fieldId": "{9135200A-5626-4DD8-AB9D-D665B8C11748}" // __Never publish 48 | }, 49 | { 50 | "fieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}" // __Owner 51 | }, 52 | { 53 | "fieldId": "{DEC8D2D5-E3CF-48B6-A653-8E69E2716641}" // __Security 54 | } 55 | ] 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/PasswordConfirmation.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceMappingFieldValue": "{1AD5CA6E-8A92-49F0-889C-D082F2849FBD}", // Password-Confirmation 3 | "destTemplateId": "{52FEC879-7D8D-46D3-BBB2-131293957709}", 4 | "destTemplateName": "PasswordConfirmation", 5 | "baseTemplateMetadataFileName": "Input.json", 6 | "fields": { 7 | "newFields": [ 8 | { 9 | "fieldType": "shared", 10 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 11 | "value": "{6293530F-36A1-4CA6-A2E6-C59C9343F096}" 12 | } 13 | ], 14 | "convertedFields": [ 15 | { 16 | "fieldConverter": "", 17 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 18 | "destFields": [ 19 | 20 | ] 21 | }, 22 | { 23 | "fieldConverter": "", 24 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 25 | "destFields": [ 26 | { 27 | "sourceElementName": "ConfirmationHelp", 28 | "destFieldId": "{2DF1637C-7CD0-43CF-A2F4-C0F66464CD16}", // Confirm Password Placeholder 29 | "fieldConverter": "" 30 | }, 31 | { 32 | "sourceElementName": "PasswordHelp", 33 | "destFieldId": "{A6972F08-CBB5-4830-A8C9-8A0AE34650D1}", // Placeholder Text 34 | "fieldConverter": "" 35 | }, 36 | { 37 | "sourceElementName": "ConfirmationTitle", 38 | "destFieldId": "{49C676D7-AEED-4F95-9CFF-CFA9C55C7718}", // Confirm Password Label 39 | "fieldConverter": "" 40 | }, 41 | { 42 | "sourceElementName": "PasswordTitle", 43 | "destFieldId": "{71FFD7B2-8B09-4F7B-8A66-1E4CEF653E8D}", // Title 44 | "fieldConverter": "" 45 | } 46 | ] 47 | } 48 | ] 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/List.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{5B672865-55D2-413E-B699-FDFC7E732CCF}", 3 | "destTemplateName": "List", 4 | "baseTemplateMetadataFileName": "Field.json", 5 | "dataValueType": "System.Collections.Generic.List`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]", 6 | "fields": { 7 | "convertedFields": [ 8 | { 9 | "fieldConverter": "", 10 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 11 | "destFields": [ 12 | // UNCOMMENT IF MIGRATING USING WFFM BEFORE VERSION 8.0 Update-1 13 | //{ 14 | // "sourceElementName": "Items", 15 | // "destFieldId": "", 16 | // "fieldConverter": "DatasourceConverter" 17 | //}, 18 | //{ 19 | // "sourceElementName": "SelectedValue", 20 | // "destFieldId": "{21ED172D-97E2-4AC4-8EAF-0A8860B891F4}", // Default Selection 21 | // "fieldConverter": "SelectedValueConverter" 22 | //} 23 | ] 24 | }, 25 | { 26 | "fieldConverter": "", 27 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 28 | "destFields": [ 29 | { 30 | "sourceElementName": "Items", 31 | "destFieldId": "", 32 | "fieldConverter": "DatasourceConverter" 33 | }, 34 | { 35 | "sourceElementName": "SelectedValue", 36 | "destFieldId": "{21ED172D-97E2-4AC4-8EAF-0A8860B891F4}", // Default Selection 37 | "fieldConverter": "SelectedValueConverter" 38 | } 39 | ] 40 | } 41 | ] 42 | }, 43 | "descendantItems": [ 44 | { 45 | "itemName": "Settings", 46 | "destTemplateName": "Folder", 47 | "isParentChild": true 48 | }, 49 | { 50 | "itemName": "Datasource", 51 | "destTemplateName": "Folder", 52 | "parentItemName": "Settings" 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Section.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceTemplateId": "{CF47DBAE-6E22-465A-B9B5-3EB6BCF9ECBF}", 3 | "sourceTemplateName": "Form Section", 4 | "destTemplateId": "{8CDDB194-F456-4A75-89B7-346F8F39F95C}", 5 | "destTemplateName": "Section", 6 | "baseTemplateMetadataFileName": "BaseTemplate.json", 7 | "fields": { 8 | "newFields": [ 9 | { 10 | "fieldType": "shared", 11 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", 12 | "value": "{447AA745-6D29-4B65-A5A3-8173AA8AF548}" 13 | }, 14 | { 15 | "fieldType": "shared", 16 | "destFieldId": "{71C6DE8E-4718-4977-B83E-B49552EE14B0}", 17 | "value": "{\"fieldConditions\":[]}" 18 | }, 19 | { 20 | "fieldType": "shared", 21 | "destFieldId": "{84ECE662-5034-40CB-9C60-744DB64BB294}", 22 | "valueType": "System.Guid.ToString" // Random Guid to String 23 | } 24 | ], 25 | "convertedFields": [ 26 | { 27 | "fieldConverter": "", 28 | "sourceFieldId": "{821724F3-30BB-4152-A770-88BC43AC175A}", // Title 29 | "destFieldId": "" 30 | }, 31 | { 32 | "fieldConverter": "", 33 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 34 | "destFields": [ 35 | { 36 | "sourceElementName": "CssClass", 37 | "destFieldId": "{7ABAA3F6-6EC0-4B65-A463-7919BFAE55AA}", // Css Class 38 | "fieldConverter": "" 39 | }, 40 | { 41 | "sourceElementName": "ShowLegend", 42 | "destFieldId": "", 43 | "fieldConverter": "" 44 | } 45 | ] 46 | }, 47 | { 48 | "fieldConverter": "", 49 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 50 | "destFields": [ 51 | { 52 | "sourceElementName": "Information", 53 | "destFieldId": "", 54 | "fieldConverter": "" 55 | } 56 | ] 57 | } 58 | ] 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Page.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{CFEE7B51-8505-45CE-B843-9358F827DF87}", 3 | "destTemplateName": "Page", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "shared", 8 | "destFieldId": "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}", 9 | "value": "0" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", 19 | "value": "sitecore\\Admin" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", 24 | "valueType": "System.Guid" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", 29 | "valueType": "System.DateTime" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", 34 | "value": "sitecore\\Admin" 35 | }, 36 | { 37 | "fieldType": "versioned", 38 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", 39 | "valueType": "System.DateTime" 40 | }, 41 | { 42 | "fieldType": "shared", 43 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", 44 | "value": "{D819B43E-C136-4392-9393-8BE7FCE32F5E}" 45 | }, 46 | { 47 | "fieldType": "shared", 48 | "destFieldId": "{71C6DE8E-4718-4977-B83E-B49552EE14B0}", 49 | "value": "{\"fieldConditions\":[]}" 50 | }, 51 | { 52 | "fieldType": "shared", 53 | "destFieldId": "{7ABAA3F6-6EC0-4B65-A463-7919BFAE55AA}", // Css Class 54 | "value": "" 55 | }, 56 | { 57 | "fieldType": "shared", 58 | "destFieldId": "{84ECE662-5034-40CB-9C60-744DB64BB294}", 59 | "valueType": "System.Guid.ToString" // Random Guid to String 60 | } 61 | ] 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Models/Metadata/MetadataTemplate.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Sitecore; 7 | 8 | namespace WFFM.ConversionTool.Library.Models.Metadata 9 | { 10 | [Serializable] 11 | public class MetadataTemplate 12 | { 13 | public Guid sourceTemplateId { get; set; } 14 | public string sourceTemplateName { get; set; } 15 | public Guid destTemplateId { get; set; } 16 | public string destTemplateName { get; set; } 17 | public string baseTemplateMetadataFileName { get; set; } 18 | public MetadataFields fields { get; set; } 19 | public Guid sourceMappingFieldId { get; set; } 20 | public string sourceMappingFieldValue { get; set; } 21 | public string dataValueType { get; set; } 22 | public string dataValueConverter { get; set; } 23 | public List descendantItems { get; set; } 24 | 25 | [Serializable] 26 | public class DescendantItem 27 | { 28 | public string itemName { get; set; } 29 | public string destTemplateName { get; set; } 30 | public bool isParentChild { get; set; } 31 | public string parentItemName { get; set; } 32 | } 33 | 34 | [Serializable] 35 | public class MetadataFields 36 | { 37 | public List existingFields { get; set; } 38 | public List newFields { get; set; } 39 | public List convertedFields { get; set; } 40 | 41 | [Serializable] 42 | public class MetadataExistingField 43 | { 44 | public Guid fieldId { get; set; } 45 | } 46 | 47 | [Serializable] 48 | public class MetadataNewField 49 | { 50 | public FieldType fieldType { get; set; } 51 | public Guid destFieldId { get; set; } 52 | public string valueType { get; set; } 53 | public string value { get; set; } 54 | public Dictionary, string> values { get; set; } 55 | } 56 | 57 | [Serializable] 58 | public class MetadataConvertedField 59 | { 60 | public string fieldConverter { get; set; } 61 | public Guid sourceFieldId { get; set; } 62 | public Guid? destFieldId { get; set; } 63 | public List destFields { get; set; } 64 | 65 | [Serializable] 66 | public class ValueXmlElementMapping 67 | { 68 | public string sourceElementName { get; set; } 69 | public Guid? destFieldId { get; set; } 70 | public string fieldConverter { get; set; } 71 | } 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/BaseFieldConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Models.Metadata; 7 | using WFFM.ConversionTool.Library.Models.Sitecore; 8 | 9 | namespace WFFM.ConversionTool.Library.Converters 10 | { 11 | public class BaseFieldConverter : IFieldConverter 12 | { 13 | public virtual string ConvertValue(string sourceValue) 14 | { 15 | return sourceValue; 16 | } 17 | 18 | public SCField ConvertField(SCField scField, Guid destFieldId) 19 | { 20 | var convertedValue = ConvertValue(scField.Value); 21 | if (convertedValue == null) return null; 22 | return CreateField(scField, destFieldId, convertedValue); 23 | } 24 | 25 | public virtual SCField ConvertValueElement(SCField scField, Guid destFieldId, string elementValue, List destItems = null) 26 | { 27 | var convertedValue = ConvertValue(elementValue); 28 | if (convertedValue == null) return null; 29 | return CreateFieldFromElement(scField, destFieldId, convertedValue); 30 | } 31 | 32 | public virtual List ConvertValueElementToItems(SCField scField, string elementValue, MetadataTemplate metadataTemplate, SCItem sourceItem) 33 | { 34 | return new List(); 35 | } 36 | 37 | public virtual List ConvertValueElementToFields(SCField scField, string elementValue) 38 | { 39 | return new List(); 40 | } 41 | 42 | public SCField CreateFieldFromElement(SCField scField, Guid destFieldId, string convertedValue) 43 | { 44 | return CreateFieldFromElement(scField, destFieldId, convertedValue, scField.Type); 45 | } 46 | 47 | public SCField CreateFieldFromElement(SCField scField, Guid destFieldId, string convertedValue, FieldType fieldType) 48 | { 49 | return new SCField() 50 | { 51 | Created = DateTime.UtcNow, 52 | Updated = DateTime.UtcNow, 53 | ItemId = scField.ItemId, 54 | Language = scField.Language, 55 | Version = scField.Version, 56 | Type = fieldType, 57 | Value = convertedValue, 58 | FieldId = destFieldId, 59 | Id = Guid.NewGuid() 60 | }; 61 | } 62 | 63 | public SCField CreateField(SCField scField, Guid destFieldId, string convertedValue) 64 | { 65 | return new SCField() 66 | { 67 | Created = DateTime.Now, 68 | Updated = DateTime.Now, 69 | ItemId = scField.ItemId, 70 | Language = scField.Language, 71 | Version = scField.Version, 72 | Type = scField.Type, 73 | Value = convertedValue, 74 | FieldId = destFieldId, 75 | Id = scField.Id 76 | }; 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /WFFM.ConversionTool.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 16 4 | VisualStudioVersion = 16.0.30104.148 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WFFM.ConversionTool.Library", "src\WFFM.ConversionTool.Library\WFFM.ConversionTool.Library.csproj", "{670AD498-F9F3-45BC-81A5-4C5841249298}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WFFM.ConversionTool", "src\WFFM.ConversionTool\WFFM.ConversionTool.csproj", "{49CD87DD-7950-4296-87B0-D5495D7A3A5A}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{A8AB7F81-859B-4B4C-84B3-08FD913AEC9C}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WFFM.ConversionTool.Extensions.SitecoreFormsExtensions", "src\WFFM.ConversionTool.Extensions.SitecoreFormsExtensions\WFFM.ConversionTool.Extensions.SitecoreFormsExtensions.csproj", "{B0F28BBF-BCDF-491B-A6D3-406F7B042C24}" 13 | EndProject 14 | Global 15 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 16 | Debug|Any CPU = Debug|Any CPU 17 | Release|Any CPU = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 20 | {670AD498-F9F3-45BC-81A5-4C5841249298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {670AD498-F9F3-45BC-81A5-4C5841249298}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {670AD498-F9F3-45BC-81A5-4C5841249298}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {670AD498-F9F3-45BC-81A5-4C5841249298}.Release|Any CPU.Build.0 = Release|Any CPU 24 | {49CD87DD-7950-4296-87B0-D5495D7A3A5A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 25 | {49CD87DD-7950-4296-87B0-D5495D7A3A5A}.Debug|Any CPU.Build.0 = Debug|Any CPU 26 | {49CD87DD-7950-4296-87B0-D5495D7A3A5A}.Release|Any CPU.ActiveCfg = Release|Any CPU 27 | {49CD87DD-7950-4296-87B0-D5495D7A3A5A}.Release|Any CPU.Build.0 = Release|Any CPU 28 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24}.Release|Any CPU.Build.0 = Release|Any CPU 32 | EndGlobalSection 33 | GlobalSection(SolutionProperties) = preSolution 34 | HideSolutionNode = FALSE 35 | EndGlobalSection 36 | GlobalSection(NestedProjects) = preSolution 37 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24} = {A8AB7F81-859B-4B4C-84B3-08FD913AEC9C} 38 | EndGlobalSection 39 | GlobalSection(ExtensibilityGlobals) = postSolution 40 | SolutionGuid = {30DFC773-BB3F-4D98-94A1-7E07A4F3078A} 41 | EndGlobalSection 42 | EndGlobal 43 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Text.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{FC18F915-EAC6-460A-8777-6E1376A9EA09}", 3 | "destTemplateName": "Text", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", // __Updated by 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", // __Created by 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", // __Revision 19 | "valueType": "System.Guid" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", // __Created 24 | "valueType": "System.DateTime" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", // __Owner 29 | "value": "sitecore\\Admin" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", // __Updated 34 | "valueType": "System.DateTime" 35 | }, 36 | { 37 | "fieldType": "unversioned", 38 | "destFieldId": "{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}", // __Display name 39 | "valueType": "System.String" 40 | }, 41 | { 42 | "fieldType": "shared", 43 | "destFieldId": "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}", // __Sort Order 44 | "value": "100" 45 | }, 46 | { 47 | "fieldType": "versioned", 48 | "destFieldId": "{9666782B-21BB-40CE-B38F-8F6C53FA5070}", // Text 49 | "valueType": "System.String" 50 | }, 51 | { 52 | "fieldType": "shared", 53 | "destFieldId": "{C6CAA979-C3AC-4FFC-861E-2961F5FC3C48}", // Html Tag 54 | "value": "p" 55 | }, 56 | { 57 | "fieldType": "shared", 58 | "destFieldId": "{71C6DE8E-4718-4977-B83E-B49552EE14B0}", // Conditions 59 | "value": "{\"fieldConditions\":[]}" 60 | }, 61 | { 62 | "fieldType": "shared", 63 | "destFieldId": "{84ECE662-5034-40CB-9C60-744DB64BB294}", // Field Key 64 | "valueType": "System.Guid.ToString" // Random Guid to String 65 | } 66 | ] 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Processors/ItemProcessor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Converters; 7 | using WFFM.ConversionTool.Library.Factories; 8 | using WFFM.ConversionTool.Library.Models.Metadata; 9 | using WFFM.ConversionTool.Library.Models.Sitecore; 10 | using WFFM.ConversionTool.Library.Repositories; 11 | 12 | namespace WFFM.ConversionTool.Library.Processors 13 | { 14 | public abstract class ItemProcessor : IItemProcessor 15 | { 16 | private IDestMasterRepository _destMasterRepository; 17 | private IItemConverter _itemConverter; 18 | private IItemFactory _itemFactory; 19 | private AppSettings _appSettings; 20 | 21 | public ItemProcessor(IDestMasterRepository destMasterRepository, IItemConverter itemConverter, IItemFactory itemFactory, AppSettings appSettings) 22 | { 23 | _destMasterRepository = destMasterRepository; 24 | _itemConverter = itemConverter; 25 | _itemFactory = itemFactory; 26 | _appSettings = appSettings; 27 | 28 | } 29 | 30 | public virtual void ConvertAndWriteItem(SCItem sourceItem, Guid parentId) 31 | { 32 | // Convert 33 | var destItems = _itemConverter.Convert(sourceItem, parentId); 34 | 35 | // Write to dest 36 | foreach (var destItem in destItems) 37 | { 38 | _destMasterRepository.AddOrUpdateSitecoreItem(destItem); 39 | } 40 | } 41 | 42 | public virtual Guid WriteNewItem(Guid destTemplateId, SCItem parentItem, string itemName, MetadataTemplate metadataTemplate = null) 43 | { 44 | var destItem = _itemFactory.Create(destTemplateId, parentItem, itemName, metadataTemplate); 45 | 46 | _destMasterRepository.AddOrUpdateSitecoreItem(destItem); 47 | 48 | return destItem.ID; 49 | } 50 | 51 | public void UpdateItem(SCItem item) 52 | { 53 | _destMasterRepository.AddOrUpdateSitecoreItem(item); 54 | } 55 | 56 | public virtual void WriteDescendentItems(MetadataTemplate metadataTemplate, SCItem parentItem) 57 | { 58 | var descendantItems = _itemFactory.CreateDescendantItems(metadataTemplate, parentItem); 59 | foreach (SCItem descendantItem in descendantItems) 60 | { 61 | _destMasterRepository.AddOrUpdateSitecoreItem(descendantItem); 62 | } 63 | } 64 | 65 | public void DeleteItem(Guid parentId, string itemName, MetadataTemplate metadataTemplate) 66 | { 67 | var textItem = _destMasterRepository.GetSitecoreChildrenItems(metadataTemplate.destTemplateId, parentId) 68 | .FirstOrDefault(item => string.Equals(item.Name, itemName, StringComparison.InvariantCultureIgnoreCase)); 69 | if (textItem != null) 70 | { 71 | _destMasterRepository.DeleteSitecoreItem(textItem); 72 | } 73 | } 74 | 75 | public SCItem CheckItemNotNullForAnalysis(SCItem item) 76 | { 77 | if (_appSettings.enableOnlyAnalysisByDefault && item == null) 78 | { 79 | item = _itemFactory.CreateDummyItem(); 80 | } 81 | 82 | return item; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Extensions.SitecoreFormsExtensions/WFFM.ConversionTool.Extensions.SitecoreFormsExtensions.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {B0F28BBF-BCDF-491B-A6D3-406F7B042C24} 8 | Library 9 | Properties 10 | WFFM.ConversionTool.Extensions.SitecoreFormsExtensions 11 | WFFM.ConversionTool.Extensions.SitecoreFormsExtensions 12 | v4.7.1 13 | 512 14 | 15 | 16 | true 17 | full 18 | false 19 | bin\Debug\ 20 | DEBUG;TRACE 21 | prompt 22 | 4 23 | 24 | 25 | pdbonly 26 | true 27 | bin\Release\ 28 | TRACE 29 | prompt 30 | 4 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | {670ad498-f9f3-45bc-81a5-4c5841249298} 48 | WFFM.ConversionTool.Library 49 | 50 | 51 | 52 | 53 | Always 54 | 55 | 56 | 57 | 58 | 59 | Always 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 |
7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/SubmitActionConverters/SendEmailConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using WFFM.ConversionTool.Library.Helpers; 9 | using WFFM.ConversionTool.Library.Logging; 10 | using WFFM.ConversionTool.Library.Models.Form; 11 | using WFFM.ConversionTool.Library.Repositories; 12 | 13 | namespace WFFM.ConversionTool.Library.Converters.SubmitActionConverters 14 | { 15 | public class SendEmailConverter : BaseFieldConverter 16 | { 17 | private IDestMasterRepository _destMasterRepository; 18 | private ILogger _logger; 19 | 20 | public SendEmailConverter(IDestMasterRepository destMasterRepository, ILogger logger) 21 | { 22 | _destMasterRepository = destMasterRepository; 23 | _logger = logger; 24 | } 25 | 26 | public override string ConvertValue(string sourceValue) 27 | { 28 | // example of sourceValue 29 | // example.hostexample@mail.nettrueto@example.comcc@example.combcc@example.comexample@mail.netThis is the subject of the email.

This is the body of the email.

[]

30 | var host = XmlHelper.GetXmlElementValue(sourceValue, "host", true); 31 | var from = XmlHelper.GetXmlElementValue(sourceValue, "from", true); 32 | var isbodyhtml = XmlHelper.GetXmlElementValue(sourceValue, "isbodyhtml", true); 33 | var to = XmlHelper.GetXmlElementValue(sourceValue, "to", true); 34 | var cc = XmlHelper.GetXmlElementValue(sourceValue, "cc", true); 35 | var bcc = XmlHelper.GetXmlElementValue(sourceValue, "bcc", true); 36 | var localfrom = XmlHelper.GetXmlElementValue(sourceValue, "localfrom", true); 37 | var subject = ConvertFieldTokens(XmlHelper.GetXmlElementValue(sourceValue, "subject", true)); 38 | var mail = ConvertFieldTokens(XmlHelper.GetXmlElementValue(sourceValue, "mail", true)); 39 | 40 | var fromValue = !string.IsNullOrEmpty(from) ? from : localfrom; 41 | 42 | return JsonConvert.SerializeObject(new 43 | SendEmailAction() { 44 | from = fromValue, 45 | to = to, 46 | cc = cc, 47 | bcc = bcc, 48 | subject = subject, 49 | body = mail 50 | }); 51 | } 52 | 53 | private string ConvertFieldTokens(string fieldText) 54 | { 55 | // Find all tokens 56 | var matches = Regex.Matches(fieldText, @"\[(.*?)\]", RegexOptions.IgnoreCase); 57 | 58 | foreach (Match match in matches) 59 | { 60 | Guid fieldId; 61 | var fieldName = string.Empty; 62 | var matchValue = match.Value.Replace("[", "").Replace("]", ""); 63 | if (Guid.TryParse(matchValue, out fieldId)) // case of token in subject field 64 | { 65 | // find field name 66 | fieldName = _destMasterRepository.GetSitecoreItem(fieldId)?.Name; 67 | 68 | } 69 | else // case of token in message field 70 | { 71 | // get field label value 72 | fieldName = XmlHelper.GetXmlElementValue(matchValue, "label", true); 73 | } 74 | 75 | if (!string.IsNullOrEmpty(fieldName)) 76 | { 77 | // replace token with label value 78 | fieldText = fieldText.Replace(matchValue, fieldName); 79 | } 80 | } 81 | 82 | return fieldText; 83 | } 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Fields/Button.json: -------------------------------------------------------------------------------- 1 | { 2 | "destTemplateId": "{94A46D66-B1B8-405D-AAE4-7B5A9CD61C5E}", 3 | "destTemplateName": "Button", 4 | "fields": { 5 | "newFields": [ 6 | { 7 | "fieldType": "versioned", 8 | "destFieldId": "{5DD74568-4D4B-44C1-B513-0AF5F4CDA34F}", 9 | "value": "sitecore\\Admin" 10 | }, 11 | { 12 | "fieldType": "versioned", 13 | "destFieldId": "{BADD9CF9-53E0-4D0C-BCC0-2D784C282F6A}", 14 | "value": "sitecore\\Admin" 15 | }, 16 | { 17 | "fieldType": "versioned", 18 | "destFieldId": "{8CDC337E-A112-42FB-BBB4-4143751E123F}", 19 | "valueType": "System.Guid" 20 | }, 21 | { 22 | "fieldType": "versioned", 23 | "destFieldId": "{25BED78C-4957-4165-998A-CA1B52F67497}", 24 | "valueType": "System.DateTime" 25 | }, 26 | { 27 | "fieldType": "versioned", 28 | "destFieldId": "{52807595-0F8F-4B20-8D2A-CB71D28C6103}", 29 | "value": "sitecore\\Admin" 30 | }, 31 | { 32 | "fieldType": "versioned", 33 | "destFieldId": "{D9CF14B1-FA16-4BA6-9288-E8A174D4D522}", 34 | "valueType": "System.DateTime" 35 | }, 36 | { 37 | "fieldType": "shared", 38 | "destFieldId": "{BA3F86A2-4A1C-4D78-B63D-91C2779C1B5E}", // __Sort Order 39 | "value": "5000" 40 | }, 41 | { 42 | "fieldType": "shared", 43 | "destFieldId": "{589A7ADE-81D4-4A60-B9E2-7EAF6AE8A563}", // Field Type 44 | "value": "{7CE25CAB-EF3A-4F73-AB13-D33BDC1E4EE2}" 45 | }, 46 | { 47 | "fieldType": "shared", 48 | "destFieldId": "{71C6DE8E-4718-4977-B83E-B49552EE14B0}", // Conditions 49 | "value": "{\"fieldConditions\":[]}" 50 | }, 51 | { 52 | "fieldType": "shared", 53 | "destFieldId": "{7ABAA3F6-6EC0-4B65-A463-7919BFAE55AA}", // Css Class 54 | "value": "" 55 | }, 56 | { 57 | "fieldType": "shared", 58 | "destFieldId": "{84ECE662-5034-40CB-9C60-744DB64BB294}", // Field Key 59 | "valueType": "System.Guid.ToString" // Random Guid to String 60 | }, 61 | { 62 | "fieldType": "versioned", 63 | "destFieldId": "{71FFD7B2-8B09-4F7B-8A66-1E4CEF653E8D}", // Title 64 | "value": "Submit" 65 | }, 66 | { 67 | "fieldType": "shared", 68 | "destFieldId": "{D842AF43-E220-48D7-9714-6EB2381D2B0C}", // Navigation Step 69 | "value": "0" 70 | }, 71 | { 72 | "fieldType": "unversioned", 73 | "destFieldId": "{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}", // __Display name 74 | "value": "Submit" 75 | } 76 | ] 77 | }, 78 | "descendantItems": [ 79 | { 80 | "itemName": "SubmitActions", 81 | "destTemplateName": "Folder", 82 | "isParentChild": true 83 | } 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Metadata/Field.json: -------------------------------------------------------------------------------- 1 | { 2 | "sourceTemplateId": "{C9E1BF85-800A-4247-A3A3-C3F5DFBFD6AA}", 3 | "sourceTemplateName": "Field", 4 | "destTemplateId": "{0908030B-4564-42EA-A6FA-C7A5A2D921A8}", 5 | "destTemplateName": "Input", 6 | "baseTemplateMetadataFileName": "BaseTemplate.json", 7 | "sourceMappingFieldId": "{35C76A0B-B630-458C-AECC-1D62C50D24FC}", // Field Link 8 | "dataValueType": "System.String", 9 | "fields": { 10 | "newFields": [ 11 | { 12 | "fieldType": "shared", 13 | "destFieldId": "{71C6DE8E-4718-4977-B83E-B49552EE14B0}", // Conditions 14 | "value": "{\"fieldConditions\":[]}" 15 | }, 16 | { 17 | "fieldType": "shared", 18 | "destFieldId": "{84ECE662-5034-40CB-9C60-744DB64BB294}", // Field Key 19 | "valueType": "System.Guid.ToString" // Random Guid to String 20 | }, 21 | { 22 | "fieldType": "shared", 23 | "destFieldId": "{D99833EA-238A-4505-90EF-C69BF3EBA946}", 24 | "value": "1" 25 | } 26 | ], 27 | "convertedFields": [ 28 | { 29 | "fieldConverter": "", 30 | "sourceFieldId": "{158836B1-DF1A-4B6D-93C1-75E27207F822}", // Save 31 | "destFieldId": "{90C4F94C-EC2C-4EE4-B4C8-F3E29CBE630E}" // Allow Save 32 | }, 33 | { 34 | "fieldConverter": "", 35 | "sourceFieldId": "{821724F3-30BB-4152-A770-88BC43AC175A}", // Title 36 | "destFieldId": "{71FFD7B2-8B09-4F7B-8A66-1E4CEF653E8D}" // Title 37 | }, 38 | { 39 | "fieldConverter": "", 40 | "sourceFieldId": "{ACD3122B-F975-433E-9802-35BC5F8FE2B4}", // Required 41 | "destFieldId": "{8A43AF61-0812-4B37-A343-96CDE3F12BB1}" // Required 42 | }, 43 | { 44 | "fieldConverter": "", 45 | "sourceFieldId": "{35C76A0B-B630-458C-AECC-1D62C50D24FC}", // Field Link 46 | "destFieldId": "" // Conversion not needed - Field Type value set by standard values of dest template 47 | }, 48 | { 49 | "fieldConverter": "", 50 | "sourceFieldId": "{358E7AA0-E3E6-4EF6-92DF-EC1301737B50}", // Parameters 51 | "destFields": [ 52 | { 53 | "sourceElementName": "CssClass", 54 | "destFieldId": "{7ABAA3F6-6EC0-4B65-A463-7919BFAE55AA}", // Css Class 55 | "fieldConverter": "" 56 | }, 57 | { 58 | "sourceElementName": "PredefinedValidator", 59 | "destFieldId": "", // Conversion not needed - Validations value set by standard values of dest template 60 | "fieldConverter": "" 61 | } 62 | ] 63 | }, 64 | { 65 | "fieldConverter": "", 66 | "sourceFieldId": "{26CDC7C2-5307-4591-A7F9-5C034A05630A}", // Localized Parameters 67 | "destFields": [ 68 | { 69 | "sourceElementName": "PredefinedValidatorTextMessage", 70 | "destFieldId": "", 71 | "fieldConverter": "" 72 | } 73 | ] 74 | } 75 | ] 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/AppSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "itemReferences": { 3 | "destFormFolderId": "{B701850A-CB8A-4943-B2BC-DDDB1238C103}", 4 | "sourceSampleFormsFolderId": "{4F42E032-6174-4A79-B3B0-5056494D6B39}" 5 | }, 6 | "converters": [ 7 | { 8 | "name": "TrackingConverter", 9 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.TrackingConverter, WFFM.ConversionTool.Library" 10 | }, 11 | { 12 | "name": "DateConverter", 13 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.DateConverter, WFFM.ConversionTool.Library" 14 | }, 15 | { 16 | "name": "YesNoConverter", 17 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.YesNoConverter, WFFM.ConversionTool.Library" 18 | }, 19 | { 20 | "name": "SelectionModeConverter", 21 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.SelectionModeConverter, WFFM.ConversionTool.Library" 22 | }, 23 | { 24 | "name": "DatasourceConverter", 25 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.DatasourceConverter, WFFM.ConversionTool.Library" 26 | }, 27 | { 28 | "name": "SelectedValueConverter", 29 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldConverters.SelectedValueConverter, WFFM.ConversionTool.Library" 30 | }, 31 | { 32 | "name": "BooleanConverter", 33 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldValueConverters.BooleanConverter, WFFM.ConversionTool.Library" 34 | }, 35 | { 36 | "name": "DateValueConverter", 37 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldValueConverters.DateValueConverter, WFFM.ConversionTool.Library" 38 | }, 39 | { 40 | "name": "FileUploadConverter", 41 | "converterType": "WFFM.ConversionTool.Library.Converters.FieldValueConverters.FileUploadConverter, WFFM.ConversionTool.Library" 42 | } 43 | ], 44 | "submitActions": [ 45 | { 46 | "sourceSaveActionId": "{D4502A11-9417-4479-9F2A-485F45D2E2D0}", 47 | "destSubmitActionItemName": "Send Email", 48 | "destSubmitActionFieldValue": "{A082C3F9-D90F-4825-8A38-8D2BE7653FC0}", 49 | "destParametersConverterType": "WFFM.ConversionTool.Library.Converters.SubmitActionConverters.SendEmailConverter, WFFM.ConversionTool.Library" 50 | } 51 | ], 52 | "enableOnlyAnalysisByDefault": true, // Default value: true. If true, the console application executed without the 'convert' parameter will not migrate forms items and data in the destination databases. 53 | "metadataFolderRelativePath": "Metadata", 54 | "invalidItemNameChars": "/:?"<>|[]", // Characters that are invalid in an item name 55 | "enableReferencedItemCheck": false, // Default value: false. If true, a referenced item will be stored in a field value only if the referenced item already exists in the destination database. 56 | "formsDataProvider": "sqlFormsDataProvider", // Default value: sqlFormsDataProvider. If "sqlFormsDataProvider", form data is migrated from wffm sql db. If "analyticsFormsDataProvider", form data is migrated from mongo db. 57 | "analysis_ExcludeBaseStandardFields": true, // Default value: true. If false, base standard fields will be included in the conversion analysis report. 58 | "excludeSampleWffmForms": true, // Default value: true. If false, sample WFFM forms will be included in the conversion process. 59 | "includeOnlyFormIds": [ 60 | //"{0E8906B3-99BA-421E-A74D-277ED17A32FD}" 61 | ], 62 | "excludeFormIds": [ 63 | //"{0E8906B3-99BA-421E-A74D-277ED17A32FD}" 64 | ], 65 | "extensions": { 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Factories/FieldFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Runtime.CompilerServices; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using WFFM.ConversionTool.Library.Models; 8 | using WFFM.ConversionTool.Library.Models.Metadata; 9 | using WFFM.ConversionTool.Library.Models.Sitecore; 10 | 11 | namespace WFFM.ConversionTool.Library.Factories 12 | { 13 | public class FieldFactory : IFieldFactory 14 | { 15 | public List CreateFields(MetadataTemplate.MetadataFields.MetadataNewField metadataNewField, Guid itemId, IEnumerable> langVersions, IEnumerable languages) 16 | { 17 | SCField destField = new SCField(); 18 | List destFields = new List(); 19 | 20 | var fieldValue = GetValue(metadataNewField.value, metadataNewField.valueType); 21 | 22 | switch (metadataNewField.fieldType) 23 | { 24 | case FieldType.Shared: 25 | destField = CreateSharedField(metadataNewField.destFieldId, itemId, fieldValue); 26 | if (destField != null) 27 | { 28 | destFields.Add(destField); 29 | } 30 | break; 31 | case FieldType.Versioned: 32 | foreach (var langVersion in langVersions) 33 | { 34 | if (metadataNewField.values != null) 35 | { 36 | fieldValue = metadataNewField.values[langVersion] ?? fieldValue; 37 | } 38 | destField = CreateVersionedField(metadataNewField.destFieldId, itemId, fieldValue, langVersion.Item2, langVersion.Item1); 39 | if (destField != null) 40 | { 41 | destFields.Add(destField); 42 | } 43 | } 44 | break; 45 | case FieldType.Unversioned: 46 | foreach (var language in languages) 47 | { 48 | var langVersion = new Tuple(language, 1); 49 | if (metadataNewField.values != null) 50 | { 51 | fieldValue = metadataNewField.values[langVersion] ?? fieldValue; 52 | } 53 | destField = CreateUnversionedField(metadataNewField.destFieldId, itemId, fieldValue, language); 54 | if (destField != null) 55 | { 56 | destFields.Add(destField); 57 | } 58 | } 59 | break; 60 | //default: 61 | //throw new ArgumentOutOfRangeException(); TODO: To implement meanful error message 62 | } 63 | 64 | return destFields; 65 | } 66 | 67 | private SCField CreateSharedField(Guid fieldId, Guid itemID, string value) 68 | { 69 | return CreateField(fieldId, itemID, value, FieldType.Shared); 70 | } 71 | 72 | private SCField CreateUnversionedField(Guid fieldId, Guid itemID, string value, string language) 73 | { 74 | return CreateField(fieldId, itemID, value, FieldType.Unversioned, null, language); 75 | } 76 | 77 | private SCField CreateVersionedField(Guid fieldId, Guid itemID, string value, int version, string language) 78 | { 79 | return CreateField(fieldId, itemID, value, FieldType.Versioned, version, language); 80 | } 81 | 82 | private SCField CreateField(Guid fieldId, Guid itemID, string value, FieldType fieldType, int? version = null, string language = null) 83 | { 84 | return new SCField() 85 | { 86 | Id = Guid.NewGuid(), 87 | FieldId = fieldId, 88 | Created = DateTime.UtcNow, 89 | ItemId = itemID, 90 | Updated = DateTime.UtcNow, 91 | Type = fieldType, 92 | Value = value, 93 | Version = version, 94 | Language = language 95 | }; 96 | } 97 | 98 | private string GetValue(string value, string valueType) 99 | { 100 | return value ?? GenerateValue(valueType); 101 | } 102 | 103 | private string GenerateValue(string valueType) 104 | { 105 | var value = string.Empty; 106 | switch (valueType.ToLower()) 107 | { 108 | case "system.datetime": 109 | value = DateTime.UtcNow.ToString("yyyyMMddThhmmssZ"); 110 | break; 111 | case "system.guid": 112 | value = Guid.NewGuid().ToString(); 113 | break; 114 | case "system.guid.tostring": 115 | value = Guid.NewGuid().ToString("N").ToUpper(); 116 | break; 117 | default: 118 | value = string.Empty; 119 | break; 120 | } 121 | 122 | return value; 123 | } 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/SectionAppearanceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Constants; 7 | using WFFM.ConversionTool.Library.Factories; 8 | using WFFM.ConversionTool.Library.Helpers; 9 | using WFFM.ConversionTool.Library.Models.Metadata; 10 | using WFFM.ConversionTool.Library.Models.Sitecore; 11 | using WFFM.ConversionTool.Library.Processors; 12 | using WFFM.ConversionTool.Library.Providers; 13 | using WFFM.ConversionTool.Library.Repositories; 14 | 15 | namespace WFFM.ConversionTool.Library.Converters 16 | { 17 | public class SectionAppearanceConverter : ItemProcessor 18 | { 19 | private IDestMasterRepository _destMasterRepository; 20 | private IMetadataProvider _metadataProvider; 21 | private IFieldProvider _fieldProvider; 22 | private AppSettings _appSettings; 23 | 24 | public SectionAppearanceConverter(IMetadataProvider metadataProvider, IDestMasterRepository destMasterRepository, IItemConverter itemConverter, IItemFactory itemFactory, IFieldProvider fieldProvider, AppSettings appSettings) 25 | : base(destMasterRepository, itemConverter, itemFactory, appSettings) 26 | { 27 | _destMasterRepository = destMasterRepository; 28 | _metadataProvider = metadataProvider; 29 | _fieldProvider = fieldProvider; 30 | _appSettings = appSettings; 31 | } 32 | 33 | public void ConvertTitle(SCItem sectionItem) 34 | { 35 | var titleItemName = "Title"; 36 | var textMetadata = _metadataProvider.GetItemMetadataByTemplateName("Text"); 37 | 38 | DeleteItem(sectionItem.ID, titleItemName, textMetadata); 39 | 40 | var parameters = sectionItem.Fields.FirstOrDefault(field => field.FieldId == new Guid(SectionConstants.SectionParametersFieldId)); 41 | if (parameters == null) return; 42 | var showLegend = XmlHelper.GetXmlElementValue(parameters.Value, SectionConstants.SectionShowLegendElementName); 43 | if (showLegend == null || string.Equals(showLegend, "Yes", StringComparison.InvariantCultureIgnoreCase)) 44 | { 45 | // Create Text Item with text in Title field using Title Tag HTML element 46 | var title = sectionItem.Fields.FirstOrDefault(field => field.FieldId == new Guid(SectionConstants.SectionTitleFieldId))?.Value; 47 | if (!string.IsNullOrEmpty(title)) 48 | { 49 | // Create Text item 50 | var fieldValues = _fieldProvider.GetFieldValues(sectionItem, new Guid(SectionConstants.SectionTitleFieldId), titleItemName); 51 | 52 | // Set text field 53 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextFieldId)).values = fieldValues; 54 | // Set Html Tag field 55 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextHtmlTagFieldId)) 56 | .value = "h2"; 57 | // Set __Sortorder field 58 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(BaseTemplateConstants.SortOrderFieldId)).value = "-100"; // First item in the section 59 | 60 | WriteNewItem(textMetadata.destTemplateId, sectionItem, titleItemName, textMetadata); 61 | } 62 | } 63 | } 64 | 65 | public void ConvertInformation(SCItem sectionItem) 66 | { 67 | var informationItemName = "Information"; 68 | var textMetadata = _metadataProvider.GetItemMetadataByTemplateName("Text"); 69 | 70 | DeleteItem(sectionItem.ID, informationItemName, textMetadata); 71 | 72 | // Create Text Item with text in Information parameter 73 | var localizedParameters = sectionItem.Fields.FirstOrDefault(field => field.FieldId == new Guid(SectionConstants.SectionLocalizedParametersFieldId))?.Value; 74 | var information = XmlHelper.GetXmlElementValue(localizedParameters, SectionConstants.SectionInformationElementName); 75 | if (!string.IsNullOrEmpty(information)) 76 | { 77 | // Create Text item 78 | var fieldValues = _fieldProvider.GetFieldValues(sectionItem, new Guid(SectionConstants.SectionLocalizedParametersFieldId), string.Empty, false); 79 | var informationFieldValues = new Dictionary, string>(); 80 | foreach (var fieldValue in fieldValues) 81 | { 82 | informationFieldValues.Add(fieldValue.Key, XmlHelper.GetXmlElementValue(fieldValue.Value, SectionConstants.SectionInformationElementName)); 83 | } 84 | 85 | // Set text field 86 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextFieldId)).values = informationFieldValues; 87 | // Set __Sortorder field 88 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(BaseTemplateConstants.SortOrderFieldId)).value = "-50"; // Second item in the page, after title 89 | 90 | WriteNewItem(textMetadata.destTemplateId, sectionItem, informationItemName, textMetadata); 91 | } 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Diagnostics; 4 | using System.Linq; 5 | using System.Security.Cryptography; 6 | using System.Text; 7 | using System.Text.RegularExpressions; 8 | using System.Threading.Tasks; 9 | using log4net; 10 | using log4net.Core; 11 | using SimpleInjector; 12 | using WFFM.ConversionTool.Library; 13 | using WFFM.ConversionTool.Library.Database; 14 | using WFFM.ConversionTool.Library.Logging; 15 | using WFFM.ConversionTool.Library.Migrators; 16 | using WFFM.ConversionTool.Library.Models.Metadata; 17 | using WFFM.ConversionTool.Library.Processors; 18 | using WFFM.ConversionTool.Library.Validators; 19 | using WFFM.ConversionTool.Library.Visualization; 20 | using ILogger = WFFM.ConversionTool.Library.Logging.ILogger; 21 | 22 | namespace WFFM.ConversionTool 23 | { 24 | class Program 25 | { 26 | static readonly Container container; 27 | 28 | private static bool help = false; 29 | private static bool convert = false; 30 | private static bool nodata = false; 31 | private static bool onlydata = false; 32 | 33 | static Program() 34 | { 35 | container = IoC.Initialize(); 36 | } 37 | 38 | static void Main(string[] args) 39 | { 40 | // Start watch 41 | var stopwatch = Stopwatch.StartNew(); 42 | 43 | // Init Console App Parameters 44 | InitializeAppParameters(args); 45 | 46 | // Render Help message if needed 47 | if (help) 48 | { 49 | Console.WriteLine(); 50 | Console.WriteLine(" Executes the conversion and migration of items and data from Sitecore WFFM source to Sitecore Experience Forms destination."); 51 | Console.WriteLine(); 52 | Console.WriteLine(" WFFM.ConversionTool.exe [-convert] [-nodata]"); 53 | Console.WriteLine(); 54 | Console.WriteLine(" -convert to convert and migrate items and data in destination databases."); 55 | Console.WriteLine(" -convert -nodata to convert and migrate only items in destination database."); 56 | Console.WriteLine(" -convert -onlydata to convert and migrate only forms data in destination database."); 57 | Console.WriteLine(); 58 | return; 59 | } 60 | 61 | // Init Console output 62 | System.Console.WriteLine(); 63 | System.Console.WriteLine(" ***********************************************************************"); 64 | System.Console.WriteLine(" * *"); 65 | System.Console.WriteLine(" * WFFM Conversion Tool - v1.6.0 *"); 66 | System.Console.WriteLine(" * *"); 67 | System.Console.WriteLine(" ***********************************************************************"); 68 | System.Console.WriteLine(); 69 | 70 | // Metadata Validation 71 | var metadataValidator = container.GetInstance(); 72 | if (!metadataValidator.Validate()) return; 73 | 74 | // AppSettings Validation 75 | var appSettingsValidator = container.GetInstance(); 76 | if (!appSettingsValidator.Validate()) return; 77 | 78 | // Connection Strings Testing 79 | var dbConnectionStringValidator = container.GetInstance(); 80 | if (!dbConnectionStringValidator.Validate()) return; 81 | 82 | // Get AppSettings instance 83 | var appSettings = container.GetInstance(); 84 | if (convert) 85 | { 86 | appSettings.enableOnlyAnalysisByDefault = false; 87 | } 88 | 89 | if (!onlydata) 90 | { 91 | // Read and analyze source data 92 | var formProcessor = container.GetInstance(); 93 | formProcessor.ConvertForms(); 94 | } 95 | 96 | if (convert && !nodata) 97 | { 98 | // Convert & Migrate data 99 | var dataMigrator = container.GetInstance(); 100 | dataMigrator.MigrateData(); 101 | } 102 | 103 | // Stop watch 104 | System.Console.WriteLine(); 105 | System.Console.WriteLine($" Execution completed in {Math.Round(stopwatch.Elapsed.TotalMinutes, 2)} minutes."); 106 | System.Console.WriteLine(); 107 | } 108 | 109 | private static void InitializeAppParameters(string[] args) 110 | { 111 | for (int i = 0; i < args.Length; i++) 112 | { 113 | string arg = args[i]; 114 | 115 | switch (arg.ToLower().Replace("/", "").Replace("-", "")) 116 | { 117 | case "help": 118 | case "?": 119 | help = true; 120 | break; 121 | case "convert": 122 | convert = true; 123 | break; 124 | case "nodata": 125 | nodata = true; 126 | break; 127 | case "onlydata": 128 | onlydata = true; 129 | break; 130 | } 131 | } 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Repositories/SourceMasterRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Database.Master; 7 | using WFFM.ConversionTool.Library.Models; 8 | using WFFM.ConversionTool.Library.Models.Sitecore; 9 | 10 | namespace WFFM.ConversionTool.Library.Repositories 11 | { 12 | public class SourceMasterRepository : ISourceMasterRepository 13 | { 14 | private SourceMasterDb _sourceMasterDb; 15 | 16 | public SourceMasterRepository(SourceMasterDb sourceMasterDb) 17 | { 18 | _sourceMasterDb = sourceMasterDb; 19 | } 20 | 21 | public SCItem GetSitecoreItem(Guid itemId) 22 | { 23 | return GetSourceItemAndFields(_sourceMasterDb.Items.FirstOrDefault(item => item.ID == itemId)); 24 | } 25 | 26 | public List GetSitecoreItems(Guid templateId) 27 | { 28 | var items = GetItems(templateId); 29 | List scItems = new List(); 30 | foreach (var item in items) 31 | { 32 | scItems.Add(GetSourceItemAndFields(item)); 33 | } 34 | 35 | return scItems; 36 | } 37 | 38 | public bool ItemHasChildrenOfTemplate(Guid templateId, SCItem scItem) 39 | { 40 | return _sourceMasterDb.Items.Any(item => item.TemplateID == templateId && item.ParentID == scItem.ID); 41 | } 42 | 43 | public List GetSitecoreChildrenItems(Guid templateId, Guid parentId) 44 | { 45 | var childrenItems = GetChildrenItems(templateId, parentId); 46 | List scItems = new List(); 47 | foreach (var item in childrenItems) 48 | { 49 | scItems.Add(GetSourceItemAndFields(item)); 50 | } 51 | 52 | return scItems; 53 | } 54 | 55 | public string GetSitecoreItemName(Guid itemId) 56 | { 57 | return _sourceMasterDb.Items.FirstOrDefault(item => item.ID == itemId)?.Name; 58 | } 59 | 60 | public string GetItemPath(Guid itemId) 61 | { 62 | var scItem = _sourceMasterDb.Items.FirstOrDefault(item => item.ID == itemId); 63 | if (scItem == null) 64 | { 65 | return string.Empty; 66 | } 67 | 68 | List itemNames = new List(); 69 | itemNames.Add(scItem.Name); 70 | var isRootSitecoreItem = false; 71 | while (!isRootSitecoreItem) 72 | { 73 | scItem = _sourceMasterDb.Items.FirstOrDefault(item => item.ID == scItem.ParentID); 74 | if (scItem == null) break; 75 | itemNames.Add(scItem.Name); 76 | isRootSitecoreItem = scItem.ID == new Guid("{11111111-1111-1111-1111-111111111111}"); 77 | } 78 | 79 | itemNames.Reverse(); 80 | return "/" + String.Join("/", itemNames); 81 | } 82 | 83 | public Guid GetItemTemplateId(Guid itemId) 84 | { 85 | return _sourceMasterDb.Items.FirstOrDefault(item => item.ID == itemId)?.TemplateID ?? Guid.Empty; 86 | } 87 | 88 | public byte[] GetSitecoreBlobData(Guid blobId) 89 | { 90 | var blobRecord = _sourceMasterDb.Blobs.FirstOrDefault(blob => blob.BlobId == blobId); 91 | 92 | return blobRecord?.Data; 93 | } 94 | 95 | private SCItem GetSourceItemAndFields(Item sourceItem) 96 | { 97 | return new SCItem() 98 | { 99 | ID = sourceItem.ID, 100 | Name = sourceItem.Name, 101 | MasterID = sourceItem.MasterID, 102 | ParentID = sourceItem.ParentID, 103 | TemplateID = sourceItem.TemplateID, 104 | Created = sourceItem.Created, 105 | Updated = sourceItem.Updated, 106 | Fields = GetItemFields(sourceItem.ID), 107 | }; 108 | } 109 | 110 | /// 111 | /// Get the list of existing items by templateId in source master database 112 | /// 113 | /// 114 | private List GetItems(Guid templateId) 115 | { 116 | return _sourceMasterDb.Items.Where(item => item.TemplateID == templateId && item.Name != "__Standard Values").ToList(); 117 | } 118 | 119 | /// 120 | /// Get the list of existing children items of a specific template of a parent item in source master database 121 | /// 122 | /// 123 | /// 124 | /// 125 | private List GetChildrenItems(Guid templateId, Guid parentId) 126 | { 127 | return _sourceMasterDb.Items.Where(item => item.TemplateID == templateId && item.Name != "__Standard Values" && item.ParentID == parentId).ToList(); 128 | } 129 | 130 | /// 131 | /// Get list of fields of a Sitecore item from the source master database 132 | /// 133 | private List GetItemFields(Guid itemId) 134 | { 135 | // fields from item template 136 | var fields = _sourceMasterDb.SharedFields.Where(field => field.ItemId == itemId) 137 | .Select(field => new SCField() { Id = field.Id, Value = field.Value, Created = field.Created, Updated = field.Updated, ItemId = field.ItemId, Type = FieldType.Shared, Language = null, Version = null, FieldId = field.FieldId }) 138 | .Union(_sourceMasterDb.UnversionedFields.Where(field => field.ItemId == itemId) 139 | .Select(field => new SCField() { Id = field.Id, Value = field.Value, Created = field.Created, Updated = field.Updated, ItemId = field.ItemId, Type = FieldType.Unversioned, Language = field.Language, Version = null, FieldId = field.FieldId })) 140 | .Union(_sourceMasterDb.VersionedFields.Where(field => field.ItemId == itemId) 141 | .Select(field => new SCField() { Id = field.Id, Value = field.Value, Created = field.Created, Updated = field.Updated, ItemId = field.ItemId, Type = FieldType.Versioned, Language = field.Language, Version = field.Version, FieldId = field.FieldId })); 142 | 143 | return fields.ToList(); 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Factories/ItemFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Text.RegularExpressions; 6 | using System.Threading.Tasks; 7 | using System.Web; 8 | using System.Web.UI; 9 | using WFFM.ConversionTool.Library.Models.Metadata; 10 | using WFFM.ConversionTool.Library.Models.Sitecore; 11 | using WFFM.ConversionTool.Library.Providers; 12 | using WFFM.ConversionTool.Library.Repositories; 13 | 14 | namespace WFFM.ConversionTool.Library.Factories 15 | { 16 | public class ItemFactory : IItemFactory 17 | { 18 | private MetadataTemplate _itemMetadataTemplate; 19 | private IMetadataProvider _metadataProvider; 20 | private IFieldFactory _fieldFactory; 21 | private AppSettings _appSettings; 22 | private IDestMasterRepository _destMasterRepository; 23 | 24 | public ItemFactory(IMetadataProvider metadataProvider, IFieldFactory fieldFactory, AppSettings appSettings, IDestMasterRepository destMasterRepository) 25 | { 26 | _metadataProvider = metadataProvider; 27 | _fieldFactory = fieldFactory; 28 | _appSettings = appSettings; 29 | _destMasterRepository = destMasterRepository; 30 | } 31 | 32 | public SCItem Create(Guid destTemplateId, SCItem parentItem, string itemName, MetadataTemplate metadataTemplate = null) 33 | { 34 | if (metadataTemplate != null) 35 | { 36 | _itemMetadataTemplate = metadataTemplate; 37 | } 38 | else 39 | { 40 | _itemMetadataTemplate = _metadataProvider.GetItemMetadataByTemplateId(destTemplateId); 41 | } 42 | 43 | itemName = RemoveInvalidChars(itemName); 44 | 45 | return CreateItem(parentItem, itemName); 46 | } 47 | 48 | public List CreateDescendantItems(MetadataTemplate metadataTemplate, SCItem parentItem) 49 | { 50 | var destItems = new List(); 51 | if (metadataTemplate.descendantItems != null) 52 | { 53 | foreach (var descendantItem in metadataTemplate.descendantItems) 54 | { 55 | if (descendantItem.isParentChild) 56 | { 57 | var destDescItem = CreateDescendantItem(descendantItem, parentItem); 58 | if (destDescItem != null) destItems.Add(destDescItem); 59 | } 60 | else 61 | { 62 | var destParentItem = destItems.FirstOrDefault(d => 63 | string.Equals(d.Name, descendantItem.parentItemName, StringComparison.InvariantCultureIgnoreCase)); 64 | if (destParentItem != null) 65 | { 66 | var destDescItem = CreateDescendantItem(descendantItem, destParentItem); 67 | if (destDescItem != null) destItems.Add(destDescItem); 68 | } 69 | } 70 | } 71 | } 72 | 73 | return destItems; 74 | } 75 | 76 | private SCItem CreateItem(SCItem parentItem, string itemName) 77 | { 78 | var itemId = Guid.NewGuid(); 79 | 80 | // Check on Guid existence (super super super rare event that the Guid already exists) 81 | while (_destMasterRepository.ItemExists(itemId)) 82 | { 83 | itemId = Guid.NewGuid(); 84 | } 85 | 86 | if (_appSettings.enableOnlyAnalysisByDefault && parentItem == null) 87 | { 88 | parentItem = CreateDummyItem(); 89 | } 90 | 91 | return new SCItem() 92 | { 93 | ID = itemId, 94 | Name = itemName, 95 | MasterID = Guid.Empty, 96 | ParentID = parentItem.ID, 97 | Created = DateTime.Now, 98 | Updated = DateTime.Now, 99 | TemplateID = _itemMetadataTemplate.destTemplateId, 100 | Fields = CreateFields(itemId, parentItem) 101 | }; 102 | } 103 | 104 | public SCItem CreateDummyItem() 105 | { 106 | return new SCItem() 107 | { 108 | ID = Guid.NewGuid(), 109 | Fields = new List() 110 | }; 111 | } 112 | 113 | private List CreateFields(Guid itemId, SCItem parentItem) 114 | { 115 | var destFields = new List(); 116 | 117 | IEnumerable> langVersions = parentItem.Fields.Where(f => f.Version != null && f.Language != null).Select(f => new Tuple(f.Language, (int)f.Version)).Distinct(); 118 | var languages = parentItem.Fields.Where(f => f.Language != null).Select(f => f.Language).Distinct(); 119 | 120 | var fieldLangVersions = _itemMetadataTemplate?.fields?.newFields?.Where(f => f.values != null).SelectMany(f => f.values.Select(v => v.Key).Distinct()).Distinct(); 121 | 122 | if (fieldLangVersions != null && fieldLangVersions.Any()) 123 | { 124 | langVersions = fieldLangVersions; 125 | languages = fieldLangVersions.Select(lv => lv.Item1).Distinct(); 126 | } 127 | 128 | foreach (var newField in _itemMetadataTemplate.fields.newFields) 129 | { 130 | destFields.AddRange(_fieldFactory.CreateFields(newField, itemId, langVersions, languages)); 131 | } 132 | 133 | return destFields; 134 | } 135 | 136 | private string RemoveInvalidChars(string itemName) 137 | { 138 | string invalidItemNameChars = _appSettings.invalidItemNameChars; 139 | if (string.IsNullOrEmpty(invalidItemNameChars)) return itemName; 140 | 141 | var invalidItemNameCharsDecoded = HttpUtility.HtmlDecode(invalidItemNameChars); 142 | var invalidItemNameCharsEscaped = invalidItemNameCharsDecoded.Replace("[", @"\[").Replace("]", @"\]"); 143 | var replaceRegex = string.Format("[" + invalidItemNameCharsEscaped + "]"); 144 | 145 | return Regex.Replace(itemName, replaceRegex, ""); 146 | } 147 | 148 | private SCItem CreateDescendantItem(MetadataTemplate.DescendantItem descendantItem, SCItem destParentItem) 149 | { 150 | if (_appSettings.enableOnlyAnalysisByDefault && destParentItem == null) 151 | { 152 | destParentItem = CreateDummyItem(); 153 | } 154 | 155 | var descendantItemMetadataTemplate = 156 | _metadataProvider.GetItemMetadataByTemplateName(descendantItem.destTemplateName); 157 | var children = _destMasterRepository.GetSitecoreChildrenItems(descendantItemMetadataTemplate.destTemplateId, 158 | destParentItem.ID); 159 | if (children != null && children.Any(i => 160 | string.Equals(i.Name, descendantItem.itemName, StringComparison.InvariantCultureIgnoreCase))) 161 | { 162 | return children.FirstOrDefault(i => 163 | string.Equals(i.Name, descendantItem.itemName, StringComparison.InvariantCultureIgnoreCase)); 164 | } 165 | return Create(descendantItemMetadataTemplate.destTemplateId, destParentItem, descendantItem.itemName); 166 | } 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Helpers/XmlHelper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Xml; 7 | using WFFM.ConversionTool.Library.Logging; 8 | 9 | namespace WFFM.ConversionTool.Library.Helpers 10 | { 11 | public static class XmlHelper 12 | { 13 | public static List GetXmlElementNames(string fieldValue) 14 | { 15 | List elementNames = new List(); 16 | XmlDocument xmlDocument = new XmlDocument(); 17 | fieldValue = SanitizeFieldValue(fieldValue); 18 | try 19 | { 20 | xmlDocument.LoadXml(AddParentNodeAndEncodeElementValue(fieldValue)); 21 | 22 | foreach (XmlNode childNode in xmlDocument.ChildNodes.Item(0).ChildNodes) 23 | { 24 | elementNames.Add(childNode.Name); 25 | } 26 | } 27 | catch (Exception e) 28 | { 29 | Console.WriteLine(); 30 | Console.WriteLine("XmlHelper - GetXmlElementNames - Failed to parse Xml value - Value = " + fieldValue); 31 | Console.WriteLine(e); 32 | Console.WriteLine(); 33 | Console.WriteLine("See logs for more details in the logs folder."); 34 | Console.WriteLine(); 35 | throw; 36 | } 37 | 38 | return elementNames; 39 | } 40 | 41 | public static string GetXmlElementValue(string fieldValue, string elementName, bool throwOnError = false) 42 | { 43 | if (!string.IsNullOrEmpty(fieldValue) && !string.IsNullOrEmpty(elementName)) 44 | { 45 | XmlDocument xmlDocument = new XmlDocument(); 46 | fieldValue = SanitizeFieldValue(fieldValue); 47 | try 48 | { 49 | xmlDocument.LoadXml(AddParentNodeAndEncodeElementValue(fieldValue)); 50 | 51 | XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName(elementName); 52 | 53 | if (elementsByTagName.Count > 0) 54 | { 55 | var element = elementsByTagName.Item(0); 56 | return element?.InnerXml; 57 | } 58 | } 59 | catch (Exception e) 60 | { 61 | Console.WriteLine(); 62 | Console.WriteLine("XmlHelper - GetXmlElementValue - Failed to parse Xml value - Value = " + fieldValue); 63 | Console.WriteLine(e); 64 | Console.WriteLine(); 65 | if (throwOnError) 66 | { 67 | Console.WriteLine("See logs for more details in the logs folder."); 68 | Console.WriteLine(); 69 | throw; 70 | } 71 | } 72 | } 73 | return string.Empty; 74 | } 75 | 76 | public static XmlNode GetXmlElementNode(string fieldValue, string elementName, bool throwOnError = false) 77 | { 78 | if (!string.IsNullOrEmpty(fieldValue) && !string.IsNullOrEmpty(elementName)) 79 | { 80 | XmlDocument xmlDocument = new XmlDocument(); 81 | fieldValue = SanitizeFieldValue(fieldValue); 82 | try 83 | { 84 | xmlDocument.LoadXml(AddParentNodeAndEncodeElementValue(fieldValue)); 85 | 86 | XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName(elementName); 87 | 88 | if (elementsByTagName.Count > 0) 89 | { 90 | return elementsByTagName.Item(0); 91 | } 92 | } 93 | catch (Exception e) 94 | { 95 | Console.WriteLine(); 96 | Console.WriteLine("XmlHelper - GetXmlElementNode - Failed to parse Xml value - Value = " + fieldValue); 97 | Console.WriteLine(e); 98 | Console.WriteLine(); 99 | if (throwOnError) 100 | { 101 | Console.WriteLine("See logs for more details in the logs folder."); 102 | Console.WriteLine(); 103 | throw; 104 | } 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | public static XmlNodeList GetXmlElementNodeList(string fieldValue, string elementName, bool throwOnError = false) 111 | { 112 | if (!string.IsNullOrEmpty(fieldValue) && !string.IsNullOrEmpty(elementName)) 113 | { 114 | XmlDocument xmlDocument = new XmlDocument(); 115 | fieldValue = SanitizeFieldValue(fieldValue); 116 | try 117 | { 118 | xmlDocument.LoadXml(AddParentNodeAndEncodeElementValue(fieldValue)); 119 | 120 | XmlNodeList elementsByTagName = xmlDocument.GetElementsByTagName(elementName); 121 | 122 | if (elementsByTagName.Count > 0) 123 | { 124 | return elementsByTagName; 125 | } 126 | } 127 | catch (Exception e) 128 | { 129 | Console.WriteLine(); 130 | Console.WriteLine("XmlHelper - GetXmlElementNodeList - Failed to parse Xml value - Value = " + fieldValue); 131 | Console.WriteLine(e); 132 | Console.WriteLine(); 133 | if (throwOnError) 134 | { 135 | Console.WriteLine("See logs for more details in the logs folder."); 136 | Console.WriteLine(); 137 | throw; 138 | } 139 | } 140 | } 141 | return null; 142 | } 143 | 144 | public static string StripHtml(string fieldValue) 145 | { 146 | if (!string.IsNullOrEmpty(fieldValue)) 147 | { 148 | XmlDocument xmlDocument = new XmlDocument(); 149 | fieldValue = SanitizeFieldValue(fieldValue); 150 | try 151 | { 152 | xmlDocument.LoadXml(AddParentNodeAndEncodeElementValue(fieldValue)); 153 | return xmlDocument.InnerText; 154 | } 155 | catch (Exception e) 156 | { 157 | Console.WriteLine(); 158 | Console.WriteLine("XmlHelper - StripHtml - Failed to parse Xml value - Value = " + fieldValue); 159 | Console.WriteLine(e); 160 | Console.WriteLine(); 161 | } 162 | 163 | } 164 | return fieldValue; 165 | } 166 | 167 | 168 | private static string AddParentNodeAndEncodeElementValue(string fieldValue) 169 | { 170 | if (!fieldValue.StartsWith("{0}", fieldValue); 174 | // Escape special chars in text value 175 | fieldValue = fieldValue.Replace(" & ", " & ").Replace(" &<"," &<"); 176 | } 177 | 178 | return fieldValue; 179 | } 180 | 181 | private static string SanitizeFieldValue(string fieldValue) 182 | { 183 | return fieldValue.Replace("
", "
") 184 | .Replace("<") 185 | .Replace("<") 186 | .Replace("<") 187 | .Replace("<") 188 | .Replace("<") 189 | .Replace("’", "’") 190 | .Replace("‘", "‘") 191 | .Replace(" "," "); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FieldConverters/DatasourceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using System.Web; 7 | using System.Xml; 8 | using WFFM.ConversionTool.Library.Factories; 9 | using WFFM.ConversionTool.Library.Helpers; 10 | using WFFM.ConversionTool.Library.Logging; 11 | using WFFM.ConversionTool.Library.Models.Metadata; 12 | using WFFM.ConversionTool.Library.Models.Sitecore; 13 | using WFFM.ConversionTool.Library.Reporting; 14 | 15 | namespace WFFM.ConversionTool.Library.Converters.FieldConverters 16 | { 17 | public class DatasourceConverter : BaseFieldConverter 18 | { 19 | private IItemFactory _itemFactory; 20 | private IReporter _analysisReporter; 21 | private ILogger _logger; 22 | 23 | public DatasourceConverter(IItemFactory itemFactory, IReporter analysisReporter, ILogger logger) 24 | { 25 | _itemFactory = itemFactory; 26 | _analysisReporter = analysisReporter; 27 | _logger = logger; 28 | } 29 | 30 | public override List ConvertValueElementToItems(SCField scField, string elementValue, MetadataTemplate metadataTemplate, SCItem sourceItem) 31 | { 32 | List convertedItems = new List(); 33 | 34 | var decodedElementValue = Uri.UnescapeDataString(elementValue).Replace("+", " "); 35 | 36 | XmlNodeList queryElements = null; 37 | try 38 | { 39 | queryElements = XmlHelper.GetXmlElementNodeList(decodedElementValue, "query", true); 40 | } 41 | catch (Exception ex) 42 | { 43 | _logger.Log(new LogEntry(LoggingEventType.Error, 44 | string.Format("ConvertValueElementToItems - Failed to parse Xml value. ItemID = {0} - FieldID = {1} - ElementName = {2} - ElementValue_Decoded = {3}", 45 | scField.ItemId, scField.Id, "query", decodedElementValue), ex)); 46 | } 47 | if (queryElements != null && queryElements.Count > 0) 48 | { 49 | foreach (XmlNode queryElement in queryElements) 50 | { 51 | if (queryElement.Attributes != null && queryElement.Attributes["t"] != null) 52 | { 53 | var queryType = queryElement.Attributes["t"].Value; 54 | if (string.Equals(queryType, "default", StringComparison.InvariantCultureIgnoreCase)) 55 | { 56 | var value = XmlHelper.GetXmlElementValue(queryElement.InnerXml, "value"); 57 | var displayName = value; 58 | var displayNames = new Dictionary, string>(); 59 | var queryChildrenElements = XmlHelper.GetXmlElementNames(queryElement.InnerXml); 60 | foreach (string queryChildrenElementName in queryChildrenElements) 61 | { 62 | if (!string.Equals(queryChildrenElementName, "value", StringComparison.InvariantCultureIgnoreCase)) 63 | { 64 | displayName = XmlHelper.GetXmlElementValue(queryElement.InnerXml, queryChildrenElementName); 65 | 66 | displayNames.Add(new Tuple(queryChildrenElementName, 1), displayName); 67 | 68 | } 69 | } 70 | 71 | if (!string.IsNullOrEmpty(value)) 72 | { 73 | // Set item value 74 | metadataTemplate.fields.newFields 75 | .First(field => field.destFieldId == new Guid("{3A07C171-9BCA-464D-8670-C5703C6D3F11}")).value = value; 76 | // Set display name 77 | if (displayNames.Any()) 78 | { 79 | metadataTemplate.fields.newFields 80 | .First(field => field.destFieldId == new Guid("{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}")).values = displayNames; 81 | } 82 | else 83 | { 84 | metadataTemplate.fields.newFields 85 | .First(field => field.destFieldId == new Guid("{B5E02AD9-D56F-4C41-A065-A133DB87BDEB}")).value = displayName; 86 | } 87 | SCItem convertedItem = _itemFactory.Create(metadataTemplate.destTemplateId, sourceItem, value, metadataTemplate); 88 | convertedItems.Add(convertedItem); 89 | } 90 | } 91 | } 92 | } 93 | } 94 | 95 | return convertedItems; 96 | } 97 | 98 | public override List ConvertValueElementToFields(SCField scField, string elementValue) 99 | { 100 | List convertedFields = new List(); 101 | 102 | var decodedElementValue = Uri.UnescapeDataString(elementValue).Replace("+"," "); 103 | 104 | XmlNode queryElement = null; 105 | try 106 | { 107 | queryElement = XmlHelper.GetXmlElementNode(decodedElementValue, "query", true); 108 | } 109 | catch (Exception ex) 110 | { 111 | _logger.Log(new LogEntry(LoggingEventType.Error, 112 | string.Format("ConvertValueElementToFields - Failed to parse Xml value. ItemID = {0} - FieldID = {1} - ElementName = {2} - ElementValue_Decoded = {3}", 113 | scField.ItemId, scField.Id, "query", decodedElementValue), ex)); 114 | } 115 | 116 | if (queryElement != null) 117 | { 118 | if (queryElement.Attributes != null && queryElement.Attributes["t"] != null) 119 | { 120 | var queryType = queryElement.Attributes["t"].Value; 121 | if (string.Equals(queryType, "root", StringComparison.InvariantCultureIgnoreCase)) 122 | { 123 | string rootItemId = XmlHelper.GetXmlElementValue(queryElement.InnerXml, "value"); 124 | string textFieldValue = queryElement.Attributes["tf"]?.Value ?? "__ItemName"; 125 | string valueFieldValue = queryElement.Attributes["vf"]?.Value ?? "__ItemName"; 126 | 127 | // Create fields 128 | var datasourceField = CreateFieldFromElement(scField, new Guid("{5BE76442-950F-4C1F-A797-BEBD71101ABB}"), rootItemId, FieldType.Shared); 129 | if (datasourceField != null) convertedFields.Add(datasourceField); 130 | 131 | if (!string.IsNullOrEmpty(textFieldValue)) 132 | { 133 | var displayField = 134 | CreateFieldFromElement(scField, new Guid("{492361E0-72D8-4847-82BA-EBFC235CF57B}"), textFieldValue, FieldType.Shared); 135 | if (displayField != null) convertedFields.Add(displayField); 136 | } 137 | 138 | if (!string.IsNullOrEmpty(valueFieldValue)) 139 | { 140 | var valueField = 141 | CreateFieldFromElement(scField, new Guid("{78778432-6327-4CEA-A28B-E190E3541D28}"), valueFieldValue, FieldType.Shared); 142 | if (valueField != null) convertedFields.Add(valueField); 143 | } 144 | 145 | var isDynamicField = CreateFieldFromElement(scField, new Guid("{54424E06-0E7A-47A7-8CB2-7383D700472F}"), "1", FieldType.Shared); 146 | if (isDynamicField != null) convertedFields.Add(isDynamicField); 147 | } 148 | } 149 | } 150 | 151 | return convertedFields; 152 | } 153 | } 154 | } 155 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Converters/FormAppearanceConverter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using WFFM.ConversionTool.Library.Constants; 7 | using WFFM.ConversionTool.Library.Factories; 8 | using WFFM.ConversionTool.Library.Helpers; 9 | using WFFM.ConversionTool.Library.Models.Metadata; 10 | using WFFM.ConversionTool.Library.Models.Sitecore; 11 | using WFFM.ConversionTool.Library.Processors; 12 | using WFFM.ConversionTool.Library.Providers; 13 | using WFFM.ConversionTool.Library.Repositories; 14 | 15 | namespace WFFM.ConversionTool.Library.Converters 16 | { 17 | public class FormAppearanceConverter : ItemProcessor 18 | { 19 | private IDestMasterRepository _destMasterRepository; 20 | private IMetadataProvider _metadataProvider; 21 | private IFieldProvider _fieldProvider; 22 | private AppSettings _appSettings; 23 | 24 | public FormAppearanceConverter(IMetadataProvider metadataProvider, IDestMasterRepository destMasterRepository, IItemConverter itemConverter, IItemFactory itemFactory, IFieldProvider fieldProvider, AppSettings appSettings) 25 | : base(destMasterRepository, itemConverter, itemFactory, appSettings) 26 | { 27 | _destMasterRepository = destMasterRepository; 28 | _metadataProvider = metadataProvider; 29 | _fieldProvider = fieldProvider; 30 | _appSettings = appSettings; 31 | } 32 | 33 | public void ConvertTitle(SCItem form, SCItem pageItem) 34 | { 35 | var titleItemName = "Title"; 36 | var textMetadata = _metadataProvider.GetItemMetadataByTemplateName("Text"); 37 | 38 | pageItem = CheckItemNotNullForAnalysis(pageItem); 39 | 40 | DeleteItem(pageItem.ID, titleItemName, textMetadata); 41 | 42 | var showTitle = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormShowTitleFieldId)); 43 | if (showTitle == null || showTitle.Value == "1") 44 | { 45 | // Create Text Item with text in Title field using Title Tag HTML element 46 | var title = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormTitleFieldId))?.Value; 47 | if (!string.IsNullOrEmpty(title)) 48 | { 49 | var titleTagField = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormTitleTagFieldId)); 50 | var titleTag = titleTagField != null ? titleTagField.Value : FormConstants.FormTitleTagStandardValue; 51 | 52 | // Create Text item 53 | var parentItem = _destMasterRepository.GetSitecoreItem(pageItem.ID); 54 | var fieldValues = _fieldProvider.GetFieldValues(form, new Guid(FormConstants.FormTitleFieldId), titleItemName); 55 | 56 | // Set text field 57 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextFieldId)).values = fieldValues; 58 | // Set Html Tag field 59 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextHtmlTagFieldId)).value = 60 | ConvertTitleTag(titleTag); 61 | // Set __Sortorder field 62 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(BaseTemplateConstants.SortOrderFieldId)).value = "-100"; // First item in the page 63 | 64 | WriteNewItem(textMetadata.destTemplateId, parentItem, titleItemName, textMetadata); 65 | } 66 | } 67 | } 68 | 69 | public void ConvertIntroduction(SCItem form, SCItem pageItem) 70 | { 71 | var introductionItemName = "Introduction"; 72 | var textMetadata = _metadataProvider.GetItemMetadataByTemplateName("Text"); 73 | 74 | pageItem = CheckItemNotNullForAnalysis(pageItem); 75 | 76 | DeleteItem(pageItem.ID, introductionItemName, textMetadata); 77 | 78 | var showIntroduction = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormShowIntroductionFieldId)); 79 | if (showIntroduction != null && showIntroduction.Value == "1") 80 | { 81 | // Create Text Item with text in Introduction field 82 | var introduction = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormIntroductionFieldId))?.Value; 83 | if (!string.IsNullOrEmpty(introduction)) 84 | { 85 | // Create Text item 86 | var parentItem = _destMasterRepository.GetSitecoreItem(pageItem.ID); 87 | var fieldValues = _fieldProvider.GetFieldValues(form, new Guid(FormConstants.FormIntroductionFieldId), string.Empty, false); 88 | 89 | // Set text field 90 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextFieldId)).values = fieldValues; 91 | // Set __Sortorder field 92 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(BaseTemplateConstants.SortOrderFieldId)).value = "-50"; // Second item in the page, after title 93 | 94 | WriteNewItem(textMetadata.destTemplateId, parentItem, introductionItemName, textMetadata); 95 | } 96 | } 97 | } 98 | 99 | public void ConvertFooter(SCItem form, SCItem pageItem) 100 | { 101 | var footerItemName = "Footer"; 102 | var textMetadata = _metadataProvider.GetItemMetadataByTemplateName("Text"); 103 | 104 | pageItem = CheckItemNotNullForAnalysis(pageItem); 105 | 106 | DeleteItem(pageItem.ID, footerItemName, textMetadata); 107 | 108 | var showFooter = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormShowFooterFieldId)); 109 | if (showFooter != null && showFooter.Value == "1") 110 | { 111 | // Create Text Item with text in Introduction field 112 | var footer = form.Fields.FirstOrDefault(field => field.FieldId == new Guid(FormConstants.FormFooterFieldId))?.Value; 113 | if (!string.IsNullOrEmpty(footer)) 114 | { 115 | // Create Text item 116 | var parentItem = _destMasterRepository.GetSitecoreItem(pageItem.ID); 117 | var fieldValues = _fieldProvider.GetFieldValues(form, new Guid(FormConstants.FormFooterFieldId), string.Empty, false); 118 | 119 | // Set text field 120 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(TextConstants.TextFieldId)).values = fieldValues; 121 | // Set __Sortorder field 122 | textMetadata.fields.newFields.First(field => field.destFieldId == new Guid(BaseTemplateConstants.SortOrderFieldId)).value = "4000"; // Second item in the page, after title 123 | 124 | WriteNewItem(textMetadata.destTemplateId, parentItem, footerItemName, textMetadata); 125 | } 126 | } 127 | } 128 | 129 | private string ConvertTitleTag(string sourceTitleTagValue) 130 | { 131 | var tagValue = sourceTitleTagValue.ToLower(); 132 | switch (tagValue) 133 | { 134 | case "a": 135 | case "b": 136 | case "strong": 137 | return "h1"; 138 | default: 139 | return tagValue; 140 | } 141 | } 142 | } 143 | } -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/Reporting/AnalysisReporter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using CsvHelper; 8 | using WFFM.ConversionTool.Library.Constants; 9 | using WFFM.ConversionTool.Library.Models.Metadata; 10 | using WFFM.ConversionTool.Library.Models.Reporting; 11 | using WFFM.ConversionTool.Library.Models.Sitecore; 12 | using WFFM.ConversionTool.Library.Repositories; 13 | 14 | namespace WFFM.ConversionTool.Library.Reporting 15 | { 16 | public class AnalysisReporter : IReporter 17 | { 18 | private List _reportingRecords = new List(); 19 | 20 | private ISourceMasterRepository _sourceMasterRepository; 21 | private AppSettings _appSettings; 22 | 23 | public string CurrentFormId { get; set; } 24 | public string CurrentFormName { get; set; } 25 | 26 | private List _convertedFieldIds = new List() 27 | { 28 | FormConstants.FormTitleFieldId, 29 | FormConstants.FormFooterFieldId, 30 | FormConstants.FormIntroductionFieldId, 31 | FormConstants.FormShowFooterFieldId, 32 | FormConstants.FormShowTitleFieldId, 33 | FormConstants.FormShowIntroductionFieldId, 34 | FormConstants.FormSaveToDatabaseFieldId, 35 | FormConstants.FormSubmitModeFieldId, 36 | FormConstants.FormSubmitNameFieldId, 37 | FormConstants.FormSuccessMessageFieldId, 38 | FormConstants.FormSuccessPageFieldId, 39 | FormConstants.FormTitleTagFieldId, 40 | FormConstants.FormSaveActionFieldId 41 | }; 42 | 43 | public AnalysisReporter(ISourceMasterRepository sourceMasterRepository, AppSettings appSettings) 44 | { 45 | _sourceMasterRepository = sourceMasterRepository; 46 | _appSettings = appSettings; 47 | } 48 | 49 | public void AddUnmappedItemField(SCField field, Guid itemId) 50 | { 51 | AddReportingRecord(new ReportingRecord() 52 | { 53 | ItemId = itemId.ToString("B").ToUpper(), 54 | ItemName = _sourceMasterRepository.GetSitecoreItemName(itemId), 55 | ItemPath = _sourceMasterRepository.GetItemPath(itemId), 56 | ItemVersion = field.Version, 57 | ItemLanguage = field.Language, 58 | ItemTemplateId = _sourceMasterRepository.GetItemTemplateId(itemId).ToString("B").ToUpper(), 59 | ItemTemplateName = _sourceMasterRepository.GetSitecoreItemName(_sourceMasterRepository.GetItemTemplateId(itemId)), 60 | FieldId = field.FieldId.ToString("B").ToUpper(), 61 | FieldName = _sourceMasterRepository.GetSitecoreItemName(field.FieldId), 62 | FieldType = field.Type.ToString(), 63 | FieldValue = field.Value, 64 | Message = "Source Field Not Mapped" 65 | }); 66 | } 67 | 68 | public void AddUnmappedFormFieldItem(Guid itemId, string sourceMappingFieldValue) 69 | { 70 | var isNotEmpty = !string.IsNullOrEmpty(sourceMappingFieldValue); 71 | 72 | AddReportingRecord(new ReportingRecord() 73 | { 74 | ItemId = itemId.ToString("B").ToUpper(), 75 | ItemName = _sourceMasterRepository.GetSitecoreItemName(itemId), 76 | ItemPath = _sourceMasterRepository.GetItemPath(itemId), 77 | ItemTemplateId = _sourceMasterRepository.GetItemTemplateId(itemId).ToString("B").ToUpper(), 78 | ItemTemplateName = _sourceMasterRepository.GetSitecoreItemName(_sourceMasterRepository.GetItemTemplateId(itemId)), 79 | Message = $"Form Field Item Not Mapped - Form Field Type Name = {(isNotEmpty ? _sourceMasterRepository.GetSitecoreItemName(Guid.Parse(sourceMappingFieldValue)) : sourceMappingFieldValue)}" 80 | }); 81 | } 82 | 83 | public void AddUnmappedSaveAction(SCField field, Guid itemId, Guid saveActionId) 84 | { 85 | AddReportingRecord(new ReportingRecord() 86 | { 87 | ItemId = itemId.ToString("B").ToUpper(), 88 | ItemName = _sourceMasterRepository.GetSitecoreItemName(itemId), 89 | ItemPath = _sourceMasterRepository.GetItemPath(itemId), 90 | ItemVersion = field.Version, 91 | ItemLanguage = field.Language, 92 | ItemTemplateId = _sourceMasterRepository.GetItemTemplateId(itemId).ToString("B").ToUpper(), 93 | ItemTemplateName = _sourceMasterRepository.GetSitecoreItemName(_sourceMasterRepository.GetItemTemplateId(itemId)), 94 | FieldId = field.FieldId.ToString("B").ToUpper(), 95 | FieldName = _sourceMasterRepository.GetSitecoreItemName(field.FieldId), 96 | FieldType = field.Type.ToString(), 97 | FieldValueReferencedItemId = saveActionId.ToString("B").ToUpper(), 98 | FieldValueReferencedItemName = _sourceMasterRepository.GetSitecoreItemName(saveActionId), 99 | Message = "Form Save Action Not Mapped" 100 | }); 101 | } 102 | 103 | public void AddUnmappedValueElementSourceField(SCField field, Guid itemId, string sourceFieldValueElementName, string sourceFieldValueElementValue) 104 | { 105 | AddReportingRecord(new ReportingRecord() 106 | { 107 | ItemId = itemId.ToString("B").ToUpper(), 108 | ItemName = _sourceMasterRepository.GetSitecoreItemName(itemId), 109 | ItemPath = _sourceMasterRepository.GetItemPath(itemId), 110 | ItemVersion = field.Version, 111 | ItemLanguage = field.Language, 112 | ItemTemplateId = _sourceMasterRepository.GetItemTemplateId(itemId).ToString("B").ToUpper(), 113 | ItemTemplateName = _sourceMasterRepository.GetSitecoreItemName(_sourceMasterRepository.GetItemTemplateId(itemId)), 114 | FieldId = field.FieldId.ToString("B").ToUpper(), 115 | FieldName = _sourceMasterRepository.GetSitecoreItemName(field.FieldId), 116 | FieldType = field.Type.ToString(), 117 | FieldValueElementName = sourceFieldValueElementName, 118 | FieldValueElementValue = sourceFieldValueElementValue, 119 | Message = "Source Field Element Value Not Mapped" 120 | }); 121 | } 122 | 123 | private void AddReportingRecord(ReportingRecord reportingRecord) 124 | { 125 | // Set global form processing values 126 | reportingRecord.FormId = CurrentFormId; 127 | reportingRecord.FormName = CurrentFormName; 128 | 129 | _reportingRecords.Add(reportingRecord); 130 | } 131 | 132 | public void GenerateOutput() 133 | { 134 | // Filter out fields converted in ad-hoc converters 135 | _reportingRecords = _reportingRecords.Where(r => !_convertedFieldIds.Contains(r.FieldId) 136 | || (string.Equals(r.FieldId, FormConstants.FormSaveActionFieldId, StringComparison.InvariantCultureIgnoreCase) 137 | && !string.IsNullOrEmpty(r.FieldValueReferencedItemId))) 138 | .OrderBy(record => record.ItemPath).ToList(); 139 | 140 | // Filter out base standard fields if analysis_ExcludeBaseStandardFields is set to true 141 | if (_appSettings.analysis_ExcludeBaseStandardFields) 142 | { 143 | _reportingRecords = _reportingRecords.Where(r => string.IsNullOrEmpty(r.FieldName) || !r.FieldName.StartsWith("__")).ToList(); 144 | } 145 | 146 | // Convert to CSV file 147 | var filePath = $"Analysis\\AnalysisReport.{DateTime.Now.ToString("yyyyMMdd.hhmmss")}.csv"; 148 | using (var writer = new StreamWriter(filePath)) 149 | using (var csv = new CsvWriter(writer)) 150 | { 151 | csv.WriteRecords(_reportingRecords); 152 | } 153 | 154 | Console.WriteLine(); 155 | Console.WriteLine(" Conversion analysis report has been generated and saved here: " + filePath); 156 | Console.WriteLine(); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /src/WFFM.ConversionTool.Library/IoC.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | using Newtonsoft.Json; 8 | using SimpleInjector; 9 | using WFFM.ConversionTool.Library.Database.Forms; 10 | using WFFM.ConversionTool.Library.Providers; 11 | using WFFM.ConversionTool.Library.Converters; 12 | using WFFM.ConversionTool.Library.Database.Master; 13 | using WFFM.ConversionTool.Library.Database.MongoDB; 14 | using WFFM.ConversionTool.Library.Factories; 15 | using WFFM.ConversionTool.Library.Logging; 16 | using WFFM.ConversionTool.Library.Migrators; 17 | using WFFM.ConversionTool.Library.Models.Metadata; 18 | using WFFM.ConversionTool.Library.Processors; 19 | using WFFM.ConversionTool.Library.Providers.FormsData; 20 | using WFFM.ConversionTool.Library.Reporting; 21 | using WFFM.ConversionTool.Library.Repositories; 22 | using WFFM.ConversionTool.Library.Validators; 23 | using Container = SimpleInjector.Container; 24 | 25 | namespace WFFM.ConversionTool.Library 26 | { 27 | public static class IoC 28 | { 29 | private static Container container = new Container(); 30 | 31 | private static readonly string _baseFieldConverterType = "WFFM.ConversionTool.Library.Converters.BaseFieldConverter, WFFM.ConversionTool.Library"; 32 | 33 | public static Container Initialize() 34 | { 35 | container.RegisterConditional(typeof(ILogger), 36 | c => typeof(Log4NetAdapter<>).MakeGenericType(c.Consumer.ImplementationType), 37 | Lifestyle.Singleton, 38 | c => true); 39 | 40 | // App Settings 41 | container.RegisterSingleton(createAppSettings); 42 | var appSettings = createAppSettings(); 43 | bool isSqlFormsDataProvider = string.Equals(appSettings.formsDataProvider, "sqlFormsDataProvider", StringComparison.InvariantCultureIgnoreCase); 44 | 45 | // Entity Framework Contexts registration 46 | container.RegisterSingleton(CreateExperienceFormsDbContext); 47 | container.RegisterSingleton(createMasterDbSourceContext); 48 | container.RegisterSingleton(createMasterDbDestContext); 49 | if (isSqlFormsDataProvider) 50 | { 51 | container.RegisterSingleton(CreateWffmDbContext); 52 | } 53 | else 54 | { 55 | container.RegisterSingleton(createMongoAnalyticsContext); 56 | } 57 | 58 | // Metadata Provider 59 | container.Register(); 60 | 61 | // Reporting 62 | container.Register(Lifestyle.Singleton); 63 | 64 | // Repositories 65 | container.Register(Lifestyle.Singleton); 66 | container.Register(Lifestyle.Singleton); 67 | container.Register(Lifestyle.Singleton); 68 | 69 | container.Register(); 70 | container.Register(); 71 | 72 | container.Register(); 73 | container.Register(); 74 | 75 | container.Register(); 76 | container.Register(); 77 | container.Register(); 78 | container.Register(); 79 | 80 | container.Register(); 81 | 82 | container.Register(); 83 | container.Register(); 84 | container.Register(); 85 | 86 | RegisterFormsDataProvider(); 87 | 88 | // Configuration to registere unregistered converter types 89 | container.ResolveUnregisteredType += (sender, e) => 90 | { 91 | if (e.UnregisteredServiceType.IsGenericType && 92 | e.UnregisteredServiceType.GetGenericTypeDefinition() == typeof(BaseFieldConverter)) 93 | { 94 | object baseConverter = container.GetInstance(typeof(BaseFieldConverter)); 95 | 96 | // Register the instance as singleton. 97 | e.Register(() => baseConverter); 98 | } 99 | }; 100 | 101 | container.Verify(); 102 | 103 | return container; 104 | } 105 | 106 | public static IFieldConverter CreateConverter(string converterName) 107 | { 108 | var converterType = _baseFieldConverterType; 109 | if (!string.IsNullOrEmpty(converterName)) 110 | { 111 | var metaConverter = createAppSettings().converters.FirstOrDefault(c => c.name == converterName)?.converterType; 112 | if (!string.IsNullOrEmpty(metaConverter)) 113 | { 114 | converterType = metaConverter; 115 | } 116 | } 117 | return CreateInstance(converterType); 118 | } 119 | 120 | public static IFieldConverter CreateInstance(string converterType) 121 | { 122 | try 123 | { 124 | if (string.IsNullOrEmpty(converterType)) 125 | return null; 126 | 127 | var type = Type.GetType(converterType); 128 | return (IFieldConverter)container.GetInstance(type); 129 | } 130 | catch (Exception ex) 131 | { 132 | // TODO: Add Logging 133 | return null; 134 | } 135 | } 136 | 137 | private static Library.Database.WFFM.WFFM CreateWffmDbContext() 138 | { 139 | var myContext = new Library.Database.WFFM.WFFM("name=WFFM"); 140 | myContext.Configuration.ProxyCreationEnabled = false; 141 | return myContext; 142 | } 143 | 144 | private static SitecoreForms CreateExperienceFormsDbContext() 145 | { 146 | var myContext = new SitecoreForms("name=SitecoreForms"); 147 | myContext.Configuration.ProxyCreationEnabled = false; 148 | return myContext; 149 | } 150 | 151 | private static SourceMasterDb createMasterDbSourceContext() 152 | { 153 | var myContext = new SourceMasterDb("name=SourceMasterDb"); 154 | myContext.Configuration.ProxyCreationEnabled = false; 155 | return myContext; 156 | } 157 | 158 | private static DestMasterDb createMasterDbDestContext() 159 | { 160 | var myContext = new DestMasterDb("name=DestMasterDb"); 161 | myContext.Configuration.ProxyCreationEnabled = false; 162 | return myContext; 163 | } 164 | 165 | private static MongoAnalytics createMongoAnalyticsContext() 166 | { 167 | var mongoDbConnectionString = 168 | System.Configuration.ConfigurationManager.ConnectionStrings["mongodb_analytics"].ConnectionString; 169 | var myContext = new MongoAnalytics(mongoDbConnectionString); 170 | return myContext; 171 | } 172 | 173 | private static AppSettings createAppSettings() 174 | { 175 | //Read json file 176 | var appSettingsFile = System.IO.File.ReadAllText("AppSettings.json"); // TODO: Add null checks 177 | // Deserialize Json to Object 178 | return JsonConvert.DeserializeObject(appSettingsFile); 179 | } 180 | 181 | private static void RegisterFormsDataProvider() 182 | { 183 | var appSettings = createAppSettings(); 184 | if (string.Equals(appSettings.formsDataProvider, "sqlFormsDataProvider", 185 | StringComparison.InvariantCultureIgnoreCase)) 186 | { 187 | container.Register(); 188 | } 189 | else if (string.Equals(appSettings.formsDataProvider, "analyticsFormsDataProvider", 190 | StringComparison.InvariantCultureIgnoreCase)) 191 | { 192 | container.Register(); 193 | } 194 | } 195 | } 196 | } 197 | --------------------------------------------------------------------------------