/// <summary> /// Add new Content Types for Pipeline Designer /// </summary> /// <remarks>Some Content Types are defined in EAV but some only in 2sxc. EAV.VersionUpgrade ensures Content Types are shared across all Apps.</remarks> internal void EnsurePipelineDesignerAttributeSets() { logger.LogStep("06.00.00", "EnsurePipelineDesignerAttributeSets start", false); // Ensure DnnSqlDataSource Configuration var dsrcSqlDataSource = ImportAttributeSet.SystemAttributeSet("|Config ToSic.SexyContent.DataSources.DnnSqlDataSource", "used to configure a DNN SqlDataSource", new List<ImportAttribute> { ImportAttribute.StringAttribute("ContentType", "ContentType", null, true), ImportAttribute.StringAttribute("SelectCommand", "SelectCommand", null, true, rowCount: 10) }); // Collect AttributeSets for use in Import var attributeSets = new List<ImportAttributeSet> { dsrcSqlDataSource }; var import = new Import(Constants.DefaultZoneId, Constants.MetaDataAppId, Settings.InternalUserName); import.RunImport(attributeSets, null); var metaDataCtx = EavDataController.Instance(Constants.DefaultZoneId, Constants.MetaDataAppId); metaDataCtx.AttribSet.GetAttributeSet(dsrcSqlDataSource.StaticName).AlwaysShareConfiguration = true; metaDataCtx.SqlDb.SaveChanges(); // Run EAV Version Upgrade (also ensures Content Type sharing) var eavVersionUpgrade = new VersionUpgrade(Settings.InternalUserName); eavVersionUpgrade.EnsurePipelineDesignerAttributeSets(); logger.LogStep("06.00.00", "EnsurePipelineDesignerAttributeSets done", false); }
/// <summary> /// Save the data in memory to the repository. /// </summary> /// <param name="userId">ID of the user doing the import</param> /// <returns>True if succeeded</returns> public bool PersistImportToRepository(string userId) { if (HasErrors) { return(false); } if (entityClear.IsAll()) { var entityDeleteGuids = GetEntityDeleteGuids(); foreach (var entityGuid in entityDeleteGuids) { var entityID = contentType.GetEntity(entityGuid).EntityID; if (contentManager.ContentContext.CanDeleteEntity(entityID).Item1) { contentManager.ContentContext.DeleteEntity(entityID); } } } var import = new ToSic.Eav.Import.Import(zoneId, applicationId, userId, true); import.RunImport(null, Entities, true, true); return(true); }
/// <summary> /// Do the import /// </summary> /// <param name="xml">The previously exported XML</param> /// <returns></returns> public bool ImportXml(int zoneId, int appId, string xml) { _sexy = new SexyContent(zoneId, appId, false); _appId = appId; _zoneId = zoneId; // Parse XDocument from string XDocument doc = XDocument.Parse(xml); if (!IsCompatible(doc)) { ImportLog.Add(new ExportImportMessage("The import file is not compatible with the installed version of 2sxc.", ExportImportMessage.MessageTypes.Error)); return(false); } // Get root node "SexyContent" XElement xmlSource = doc.Element("SexyContent"); PrepareFileIdCorrectionList(xmlSource); #region Prepare dimensions _sourceDimensions = xmlSource.Element("Header").Element("Dimensions").Elements("Dimension").Select(p => new Dimension() { DimensionID = int.Parse(p.Attribute("DimensionID").Value), Name = p.Attribute("Name").Value, SystemKey = p.Attribute("SystemKey").Value, ExternalKey = p.Attribute("ExternalKey").Value, Active = Boolean.Parse(p.Attribute("Active").Value) }).ToList(); _sourceDefaultLanguage = xmlSource.Element("Header").Element("Language").Attribute("Default").Value; _sourceDefaultDimensionId = _sourceDimensions.Any() ? _sourceDimensions.FirstOrDefault(p => p.ExternalKey == _sourceDefaultLanguage).DimensionID : new int?(); _targetDimensions = _sexy.ContentContext.GetDimensionChildren("Culture"); if (_targetDimensions.Count == 0) { _targetDimensions.Add(new Dimension() { Active = true, ExternalKey = PortalSettings.Current.DefaultLanguage, Name = "(added by import System, default language " + PortalSettings.Current.DefaultLanguage + ")", SystemKey = "Culture" }); } #endregion var importAttributeSets = GetImportAttributeSets(xmlSource.Element("AttributeSets").Elements("AttributeSet")); var importEntities = GetImportEntities(xmlSource.Elements("Entities").Elements("Entity"), SexyContent.AssignmentObjectTypeIDDefault); var import = new ToSic.Eav.Import.Import(_zoneId, _appId, PortalSettings.Current.UserInfo.DisplayName); import.RunImport(importAttributeSets, importEntities, true, true); ImportLog.AddRange(GetExportImportMessagesFromImportLog(import.ImportLog)); if (xmlSource.Elements("Templates").Any()) { if (_sexy.TemplateContext.Connection.State != ConnectionState.Open) { _sexy.TemplateContext.Connection.Open(); } var transaction = _sexy.TemplateContext.Connection.BeginTransaction(); List <Entity> templateDescribingEntities; ImportXmlTemplates(xmlSource, out templateDescribingEntities); var import2 = new ToSic.Eav.Import.Import(_zoneId, _appId, PortalSettings.Current.UserInfo.DisplayName); import2.RunImport(new List <AttributeSet>(), templateDescribingEntities, true, true); ImportLog.AddRange(GetExportImportMessagesFromImportLog(import2.ImportLog)); transaction.Commit(); } return(true); }
public static void Import(this Entity entity, int zoneId, int appId, string userName) { var import = new ToSic.Eav.Import.Import(zoneId, appId, userName, true); import.RunImport(null, new Entity[] { entity }, true, true); }
/// <summary> /// Do the import /// </summary> public bool ImportXml(int zoneId, int appId, XDocument doc, bool leaveExistingValuesUntouched = true) { //_sexy = new SxcInstance(zoneId, appId); // 2016-03-26 2dm this used to have a third parameter false = don't enable caching, which hasn't been respected for a while; removed it // App = new App(zoneId, appId, PortalSettings.Current); // 2016-04-07 2dm refactored this out of this, as using App had side-effects _eavContext = EavDataController.Instance(zoneId, appId); _appId = appId; _zoneId = zoneId; if (!IsCompatible(doc)) { ImportLog.Add(new ExportImportMessage("The import file is not compatible with the installed version of 2sxc.", ExportImportMessage.MessageTypes.Error)); return false; } // Get root node "SexyContent" var xmlSource = doc.Element(XmlConstants.RootNode); if (xmlSource == null) { ImportLog.Add(new ExportImportMessage("Xml doesn't have expected root node: " + XmlConstants.RootNode, ExportImportMessage.MessageTypes.Error)); return false; } PrepareFolderIdCorrectionListAndCreateMissingFolders(xmlSource); PrepareFileIdCorrectionList(xmlSource); #region Prepare dimensions _sourceDimensions = xmlSource.Element(XmlConstants.Header)?.Element(XmlConstants.Dimensions)?.Elements(XmlConstants.Dim).Select(p => new Dimension { DimensionID = int.Parse(p.Attribute(XmlConstants.DimId).Value), Name = p.Attribute("Name").Value, SystemKey = p.Attribute("SystemKey").Value, ExternalKey = p.Attribute("ExternalKey").Value, Active = Parse(p.Attribute("Active").Value) }).ToList(); _sourceDefaultLanguage = xmlSource.Element(XmlConstants.Header)?.Element(XmlConstants.Language)?.Attribute(XmlConstants.LangDefault).Value; if (_sourceDimensions == null || _sourceDefaultLanguage == null) { ImportLog.Add(new ExportImportMessage("Cant find source dimensions or source-default language.", ExportImportMessage.MessageTypes.Error)); return false; } _sourceDefaultDimensionId = _sourceDimensions.Any() ? _sourceDimensions.FirstOrDefault(p => p.ExternalKey == _sourceDefaultLanguage)?.DimensionID : new int?(); _targetDimensions = _eavContext.Dimensions.GetDimensionChildren("Culture"); if (_targetDimensions.Count == 0) _targetDimensions.Add(new Dimension { Active = true, ExternalKey = DefaultLanguage, Name = "(added by import System, default language " + DefaultLanguage + ")", SystemKey = "Culture" }); #endregion var atsNodes = xmlSource.Element(XmlConstants.AttributeSets)?.Elements(XmlConstants.AttributeSet); var entNodes = xmlSource.Elements(XmlConstants.Entities).Elements(XmlConstants.Entity); var importAttributeSets = GetImportAttributeSets(atsNodes); var importEntities = GetImportEntities(entNodes, ContentTypeHelpers.AssignmentObjectTypeIDDefault); var import = new Import(_zoneId, _appId, UserName, leaveExistingValuesUntouched); import.RunImport(importAttributeSets, importEntities); ImportLog.AddRange(GetExportImportMessagesFromImportLog(import.ImportLog)); if (xmlSource.Elements(XmlConstants.Templates).Any()) ImportXmlTemplates(xmlSource); return true; }
private Import.ImportEntity GetEntity(int assignmentObjectTypeId, string attributeSetStaticName, Guid? entityGuid, int? keyNumber, Import.ImportAttributeSet importAttributeSet, Guid? relatedEntity = null) { var entity = new Import.ImportEntity { AssignmentObjectTypeId = assignmentObjectTypeId, AttributeSetStaticName = attributeSetStaticName, EntityGuid = entityGuid, KeyNumber = keyNumber }; entity.Values = GetEntityValues(entity, importAttributeSet, relatedEntity); return entity; }
private static IValueImportModel GetValue(Import.ImportEntity importEntity, Guid? relatedEntity, Import.ImportAttribute importAttribute, string language, bool isUpdate, string now) { IValueImportModel value; switch (importAttribute.Type) { case "Boolean": //value = new ValueImportModel<bool?>(entity) { Value = true }; value = new ValueImportModel<bool?>(importEntity); // Test null-Value break; case "DateTime": value = new ValueImportModel<DateTime?>(importEntity) { Value = DateTime.Now }; break; case "Entity": var entities = new List<Guid>(); if (relatedEntity.HasValue) entities.Add(relatedEntity.Value); value = new ValueImportModel<List<Guid>>(importEntity) { Value = entities }; break; case "Hyperlink": value = new ValueImportModel<string>(importEntity) { Value = "http://www.2sic.com" + (isUpdate ? " Updated " + now : "") }; break; case "Number": value = new ValueImportModel<decimal?>(importEntity) { Value = (decimal?)123.12d }; break; case "String": value = new ValueImportModel<string>(importEntity) { Value = "SampleString " + importAttribute.StaticName + " " + language + (isUpdate ? " Updated" + now : "") }; break; default: throw new ArgumentOutOfRangeException(importAttribute.Type); } value.ValueDimensions = new List<Import.ValueDimension> { new Import.ValueDimension {DimensionExternalKey = language, ReadOnly = false} }; return value; }
private static Dictionary<string, List<IValueImportModel>> GetEntityValues(Import.ImportEntity importEntity, Import.ImportAttributeSet importAttributeSet, Guid? relatedEntity = null, bool isUpdate = false, string now = null) { var values = new Dictionary<string, List<IValueImportModel>>(); foreach (var attribute in importAttributeSet.Attributes) { values.Add(attribute.StaticName, new List<IValueImportModel> { GetValue(importEntity, relatedEntity, attribute, "de-de", isUpdate, now), GetValue(importEntity, relatedEntity, attribute, "en-us", isUpdate, now) }); } // Test value for invalid AttributeSet //values.Add("Test must fail", new List<IValueImportModel> { GetValue(entity, relatedEntity, attributeSet.Attributes.First(), "de-de") }); return values; }
/// <summary> /// Import a new Entity /// </summary> internal Entity AddEntity(int attributeSetId, Import.ImportEntity importEntity, List<ImportLogItem> importLog, bool isPublished, int? publishedTarget) { return AddEntity(null, attributeSetId, importEntity.Values, null, importEntity.KeyNumber, importEntity.KeyGuid, importEntity.KeyString, importEntity.AssignmentObjectTypeId, 0, importEntity.EntityGuid, null, updateLog: importLog, isPublished: isPublished, publishedEntityId: publishedTarget); }
/// <summary> /// Create Pipeline Designer Entities if they don't exist yet. Uses the EAV Import API. /// </summary> public void EnsurePipelineDesignerAttributeSets() { #region Define AttributeSets for DataPipeline and DataPipelinePart var pipelinesAttributeSet = Import.ImportAttributeSet.SystemAttributeSet(Constants.DataPipelineStaticName, "Describes a set of data sources and how they are interconnected.", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("Name", "Pipeline name", "Descriptive Name", true), Import.ImportAttribute.StringAttribute("Description", "Description", "Short info about this pipeline, what it's for", true), Import.ImportAttribute.BooleanAttribute("AllowEdit", "Allow Edit", "If set to false, the pipeline-system will only show this pipeline but not allow changes.", true, true), Import.ImportAttribute.StringAttribute("StreamsOut", "Streams Out", "Comma separated list of streams this pipeline offers to the target. Like 'Content, Presentation, ListContent, ListPresentation'", false), Import.ImportAttribute.StringAttribute("StreamWiring", "Stream Wiring", "List of connections between the parts of this pipeline, each connection on one line, like 6730:Default>6732:Default", false, rowCount: 10), Import.ImportAttribute.StringAttribute("TestParameters", "Test-Parameters", "Static Parameters to test the Pipeline with. Format as [Token:Property]=Value", true, rowCount: 10) }); var pipelinePartsAttributeSet = Import.ImportAttributeSet.SystemAttributeSet(Constants.DataPipelinePartStaticName, "A part in the data pipeline, usually a data source/target element.", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("Name", "Name", "The part name for easy identification by the user", true), Import.ImportAttribute.StringAttribute("Description", "Description", "Notes about this item", true), Import.ImportAttribute.StringAttribute("PartAssemblyAndType", "Part Assembly and Type", "Assembly and type info to help the system find this dll etc.", true), Import.ImportAttribute.StringAttribute("VisualDesignerData", "Visual Designer Data", "Technical data for the designer so it can save it's values etc.", true), }); #endregion #region Define AttributeSets for DataSources Configurations var dsrcApp = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.App", "used to configure an App DataSource", new List<Import.ImportAttribute>()); var dsrcAttributeFilter = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.AttributeFilter", "used to configure an AttributeFilter DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("AttributeNames", "AttributeNames", null, true), }); var dsrcEntityIdFilter = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.EntityIdFilter", "used to configure an EntityIdFilter DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("EntityIds", "EntityIds", "Comma separated list of Entity IDs, like 503,522,5066,32", true), //Import.AttributeHelperTools.BooleanAttribute("PassThroughOnEmptyEntityIds", "Pass-Throught on empty EntityIds", "If this is true and EntityIds results to an empty list, all entities are passed through.", true, false), }); var dsrcEntityTypeFilter = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.EntityTypeFilter", "used to configure an EntityTypeFilter DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("TypeName", "TypeName", null, true), }); var dsrcValueFilter = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.ValueFilter", "used to configure a ValueFilter DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("Attribute", "Attribute", null, true), Import.ImportAttribute.StringAttribute("Value", "Value", null, true), //Import.AttributeHelperTools.BooleanAttribute("PassThroughOnEmptyValue", "Pass-Throught on empty Value", "If this is true and Value results to an empty string, all entities are passed through.", true, false) }); var dsrcValueSort = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.ValueSort", "used to configure a ValueSort DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("Attributes", "Attributes", null, true), Import.ImportAttribute.StringAttribute("Directions", "Directions", null, true), }); var dsrcRelationshipFilter = Import.ImportAttributeSet.SystemAttributeSet("|Config ToSic.Eav.DataSources.RelationshipFilter", "used to configure a RelationshipFilter DataSource", new List<Import.ImportAttribute> { Import.ImportAttribute.StringAttribute("Relationship", "Relationship", null, true), Import.ImportAttribute.StringAttribute("Filter", "Filter", null, true), //Import.AttributeHelperTools.BooleanAttribute("PassThroughOnEmptyFilter", "Pass-Throught on empty Filter", "If this is true and Filter results to an empty string, all entities are passed through.", true, false), }); #endregion // Collect AttributeSets for use in Import var attributeSets = new List<Import.ImportAttributeSet> { pipelinesAttributeSet, pipelinePartsAttributeSet, dsrcApp, dsrcAttributeFilter, dsrcEntityIdFilter, dsrcEntityTypeFilter, dsrcValueFilter, dsrcValueSort, dsrcRelationshipFilter }; // try to access cache before we start the import, to ensure it's available afterwards (very, very important!) var cache = DataSource.GetCache(Constants.DefaultZoneId, Constants.MetaDataAppId); var x = cache.LightList.First(); var import = new Import.Import(Constants.DefaultZoneId, Constants.MetaDataAppId, _userName); import.RunImport(attributeSets, null); #region Mark all AttributeSets as shared and ensure they exist on all Apps foreach (var attributeSet in attributeSets) _metaDataCtx.AttribSet.GetAttributeSet(attributeSet.StaticName).AlwaysShareConfiguration = true; _metaDataCtx.SqlDb.SaveChanges(); _metaDataCtx.AttribSet.EnsureSharedAttributeSets(); #endregion }
// Todo / warning: highly duplicate code with ValueImportModel.cs // but can't quickly refactor, because it's still a bit different private static IValueImportModel GetValueModel(Import.ImportEntity importEntity, string valueString, string valueType, string valueLanguage = null, bool valueRedOnly = false, bool resolveHyperlink = false) { IValueImportModel valueModel; var valueConverter = Factory.Container.Resolve<IEavValueConverter>(); var type = AttributeTypeEnum.Undefined; if (valueType != null && Enum.IsDefined(typeof(AttributeTypeEnum), valueType)) type = (AttributeTypeEnum)Enum.Parse(typeof(AttributeTypeEnum), valueType); switch (type) { case AttributeTypeEnum.Boolean: { valueModel = new ValueImportModel<bool?>(importEntity) { Value = string.IsNullOrEmpty(valueString) ? null : new Boolean?(Boolean.Parse(valueString)) }; } break; case AttributeTypeEnum.Number: { valueModel = new ValueImportModel<decimal?>(importEntity) { Value = string.IsNullOrEmpty(valueString) ? null : new Decimal?(Decimal.Parse(valueString)) }; } break; case AttributeTypeEnum.DateTime: { valueModel = new ValueImportModel<DateTime?>(importEntity) { Value = string.IsNullOrEmpty(valueString) ? null : new DateTime?(DateTime.Parse(valueString.Replace("T", " ").Replace("Z", " "))) }; } break; case AttributeTypeEnum.Hyperlink: { string valueReference; if (string.IsNullOrEmpty(valueString) || !resolveHyperlink) valueReference = valueString; else { valueReference = valueConverter.Convert(ConversionScenario.ConvertFriendlyToData, valueType, valueString); } valueModel = new ValueImportModel<string>(importEntity) { Value = valueReference }; } break; case AttributeTypeEnum.Entity: { // trying to re-use existing code valueModel = ValueImportModel.GenerateLightValueImportModel(valueString, valueType, importEntity); //valueModel = new ValueImportModel<List<Guid>>(importEntity) //{ // Value = string.IsNullOrEmpty(valueString) // ? new List<Guid?>() // : valueString.Split(',').Select(Guid.Parse).ToList() //}; } break; case AttributeTypeEnum.String: case AttributeTypeEnum.Custom: default: { // String valueModel = new ValueImportModel<string>(importEntity) { Value = valueString }; } break; } if (valueLanguage != null) { valueModel.AppendLanguageReference(valueLanguage, valueRedOnly); } return valueModel; }