/// <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> private static void EnsurePipelineDesignerAttributeSets() { // Ensure DnnSqlDataSource Configuration var dsrcSqlDataSource = Eav.Import.AttributeSet.SystemAttributeSet("|Config ToSic.SexyContent.DataSources.DnnSqlDataSource", "used to configure a DNN SqlDataSource", new List <Eav.Import.Attribute> { Eav.Import.Attribute.StringAttribute("ContentType", "ContentType", null, true), Eav.Import.Attribute.StringAttribute("SelectCommand", "SelectCommand", null, true, rowCount: 10) }); // Collect AttributeSets for use in Import var attributeSets = new List <Eav.Import.AttributeSet> { dsrcSqlDataSource }; var import = new Eav.Import.Import(DataSource.DefaultZoneId, DataSource.MetaDataAppId, SexyContent.InternalUserName); import.RunImport(attributeSets, null); var metaDataCtx = EavContext.Instance(DataSource.DefaultZoneId, DataSource.MetaDataAppId); metaDataCtx.GetAttributeSet(dsrcSqlDataSource.StaticName).AlwaysShareConfiguration = true; metaDataCtx.SaveChanges(); // Run EAV Version Upgrade (also ensures Content Type sharing) var eavVersionUpgrade = new VersionUpgrade(SexyContent.InternalUserName); eavVersionUpgrade.EnsurePipelineDesignerAttributeSets(); }
/// <summary> /// Do the import /// </summary> public bool ImportXml(int zoneId, int appId, XDocument doc, bool leaveExistingValuesUntouched = true) { _sexy = new SexyContent(zoneId, appId, false); _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("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.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 importAttributeSets = GetImportAttributeSets(xmlSource.Element("AttributeSets").Elements("AttributeSet")); var importEntities = GetImportEntities(xmlSource.Elements("Entities").Elements("Entity"), SexyContent.AssignmentObjectTypeIDDefault); var import = new Eav.Import.Import(_zoneId, _appId, UserName, leaveExistingValuesUntouched); import.RunImport(importAttributeSets, importEntities); ImportLog.AddRange(GetExportImportMessagesFromImportLog(import.ImportLog)); if (xmlSource.Elements("Templates").Any()) ImportXmlTemplates(xmlSource); return true; }
/// <summary> /// Add ContentTypes for ContentGroup and move all 2sxc data to EAV /// </summary> internal void Version070000() { logger.LogStep("07.00.00", "Start", false); var userName = "******"; #region 1. Import new ContentTypes for ContentGroups and Templates logger.LogStep("07.00.00", "1. Import new ContentTypes for ContentGroups and Templates", false); if (DataSource.GetCache(Constants.DefaultZoneId, Constants.MetaDataAppId).GetContentType("2SexyContent-Template") == null) { var xmlToImport = File.ReadAllText(HttpContext.Current.Server.MapPath("~/DesktopModules/ToSIC_SexyContent/Upgrade/07.00.00.xml")); //var xmlToImport = File.ReadAllText("../../../../Upgrade/07.00.00.xml"); var xmlImport = new XmlImport("en-US", userName, true); var success = xmlImport.ImportXml(Constants.DefaultZoneId, Constants.MetaDataAppId, XDocument.Parse(xmlToImport)); if (!success) { var messages = String.Join("\r\n- ", xmlImport.ImportLog.Select(p => p.Message).ToArray()); throw new Exception("The 2sxc module upgrade to 07.00.00 failed: " + messages); } } #endregion // 2. Move all existing data to the new ContentTypes - Append new IDs to old data (ensures that we can fix things that went wrong after upgrading the module) #region Prepare Templates logger.LogStep("07.00.00", "2. Move all existing data to the new ContentTypes - Append new IDs to old data (ensures that we can fix things that went wrong after upgrading the module)", false); var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["SiteSqlServer"].ConnectionString); var templates = new DataTable(); const string sqlCommand = @"SELECT ToSIC_SexyContent_Templates.TemplateID, ToSIC_SexyContent_Templates.PortalID, ToSIC_SexyContent_Templates.Name, ToSIC_SexyContent_Templates.Path, ToSIC_SexyContent_Templates.AttributeSetID, ToSIC_SexyContent_Templates.DemoEntityID, ToSIC_SexyContent_Templates.Script, ToSIC_SexyContent_Templates.IsFile, ToSIC_SexyContent_Templates.Type, ToSIC_SexyContent_Templates.IsHidden, ToSIC_SexyContent_Templates.Location, ToSIC_SexyContent_Templates.UseForList, ToSIC_SexyContent_Templates.UseForItem, ToSIC_SexyContent_Templates.SysCreated, ToSIC_SexyContent_Templates.SysCreatedBy, ToSIC_SexyContent_Templates.SysModified, ToSIC_SexyContent_Templates.SysModifiedBy, ToSIC_SexyContent_Templates.SysDeleted, ToSIC_SexyContent_Templates.SysDeletedBy, ToSIC_SexyContent_Templates.AppID, ToSIC_SexyContent_Templates.PublishData, ToSIC_SexyContent_Templates.StreamsToPublish, ToSIC_SexyContent_Templates.PipelineEntityID, ToSIC_SexyContent_Templates.ViewNameInUrl, ToSIC_SexyContent_Templates.Temp_PresentationTypeID, ToSIC_SexyContent_Templates.Temp_PresentationDemoEntityID, ToSIC_SexyContent_Templates.Temp_ListContentTypeID, ToSIC_SexyContent_Templates.Temp_ListContentDemoEntityID, ToSIC_SexyContent_Templates.Temp_ListPresentationTypeID, ToSIC_SexyContent_Templates.Temp_ListPresentationDemoEntityID, ToSIC_SexyContent_Templates.Temp_NewTemplateGuid, ToSIC_EAV_Apps.ZoneID, ToSIC_EAV_Entities_1.EntityGUID AS ContentDemoEntityGuid, ToSIC_EAV_Entities_2.EntityGUID AS PresentationDemoEntityGuid, ToSIC_EAV_Entities_3.EntityGUID AS ListContentDemoEntityGuid, ToSIC_EAV_Entities_4.EntityGUID AS ListPresentationDemoEntityGuid, ToSIC_EAV_Entities.EntityGUID AS PipelineEntityGuid FROM ToSIC_SexyContent_Templates INNER JOIN ToSIC_EAV_Apps ON ToSIC_SexyContent_Templates.AppID = ToSIC_EAV_Apps.AppID LEFT OUTER JOIN ToSIC_EAV_Entities ON ToSIC_SexyContent_Templates.PipelineEntityID = ToSIC_EAV_Entities.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_3 ON ToSIC_SexyContent_Templates.Temp_ListContentDemoEntityID = ToSIC_EAV_Entities_3.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_1 ON ToSIC_SexyContent_Templates.DemoEntityID = ToSIC_EAV_Entities_1.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_2 ON ToSIC_SexyContent_Templates.Temp_PresentationDemoEntityID = ToSIC_EAV_Entities_2.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_4 ON ToSIC_SexyContent_Templates.Temp_ListPresentationDemoEntityID = ToSIC_EAV_Entities_4.EntityID WHERE (ToSIC_SexyContent_Templates.SysDeleted IS NULL) AND ((SELECT COUNT(*) FROM ToSIC_EAV_Entities WHERE EntityGUID = ToSIC_SexyContent_Templates.Temp_NewTemplateGuid) = 0)"; var adapter = new SqlDataAdapter(sqlCommand, sqlConnection); adapter.SelectCommand.CommandTimeout = 3600; adapter.Fill(templates); var existingTemplates = templates.AsEnumerable().Select(t => { var templateId = (int)t["TemplateID"]; var zoneId = (int)t["ZoneID"]; var appId = (int)t["AppID"]; var cache = ((BaseCache)DataSource.GetCache(zoneId, appId)).GetContentTypes(); #region Helper Functions Func <int?, string> getContentTypeStaticName = contentTypeId => { if (!contentTypeId.HasValue || contentTypeId == 0) { return(""); } if (cache.Any(c => c.Value.AttributeSetId == contentTypeId)) { return(cache[contentTypeId.Value].StaticName); } return(""); }; #endregion // Create anonymous object to validate the types var tempTemplate = new { TemplateID = templateId, Name = (string)t["Name"], Path = (string)t["Path"], NewEntityGuid = Guid.Parse((string)t["Temp_NewTemplateGuid"]), //AlreadyImported = t["Temp_NewTemplateGuid"] != DBNull.Value, ContentTypeId = getContentTypeStaticName(t["AttributeSetID"] == DBNull.Value ? new int?() : (int)t["AttributeSetID"]), ContentDemoEntityGuids = t["ContentDemoEntityGuid"] == DBNull.Value ? new List <Guid>() : new List <Guid> { (Guid)t["ContentDemoEntityGuid"] }, PresentationTypeId = getContentTypeStaticName((int)t["Temp_PresentationTypeID"]), PresentationDemoEntityGuids = t["PresentationDemoEntityGuid"] == DBNull.Value ? new List <Guid>() : new List <Guid> { (Guid)t["PresentationDemoEntityGuid"] }, ListContentTypeId = getContentTypeStaticName((int)t["Temp_ListContentTypeID"]), ListContentDemoEntityGuids = t["ListContentDemoEntityGuid"] == DBNull.Value ? new List <Guid>() : new List <Guid> { (Guid)t["ListContentDemoEntityGuid"] }, ListPresentationTypeId = getContentTypeStaticName((int)t["Temp_ListPresentationTypeID"]), ListPresentationDemoEntityGuids = t["ListPresentationDemoEntityGuid"] == DBNull.Value ? new List <Guid>() : new List <Guid> { (Guid)t["ListPresentationDemoEntityGuid"] }, Type = (string)t["Type"], IsHidden = (bool)t["IsHidden"], Location = (string)t["Location"], UseForList = (bool)t["UseForList"], AppId = appId, PublishData = (bool)t["PublishData"], StreamsToPublish = (string)t["StreamsToPublish"], PipelineEntityGuids = t["PipelineEntityGuid"] == DBNull.Value ? new List <Guid>() : new List <Guid> { (Guid)t["PipelineEntityGuid"] }, ViewNameInUrl = t["ViewNameInUrl"].ToString(), ZoneId = zoneId }; return(tempTemplate); }).ToList(); #endregion #region Prepare ContentGroups logger.LogStep("07.00.00", "2. Prepare Content Groups", false); var contentGroupItemsTable = new DataTable(); const string sqlCommandContentGroups = @"SELECT DISTINCT ToSIC_SexyContent_ContentGroupItems.ContentGroupItemID, ToSIC_SexyContent_ContentGroupItems.ContentGroupID, ToSIC_SexyContent_ContentGroupItems.TemplateID, ToSIC_SexyContent_ContentGroupItems.SortOrder, ToSIC_SexyContent_ContentGroupItems.Type, ToSIC_SexyContent_ContentGroupItems.SysCreated, ToSIC_SexyContent_ContentGroupItems.SysCreatedBy, ToSIC_SexyContent_ContentGroupItems.SysModified, ToSIC_SexyContent_ContentGroupItems.SysModifiedBy, ToSIC_SexyContent_ContentGroupItems.SysDeleted, ToSIC_SexyContent_ContentGroupItems.SysDeletedBy, ToSIC_SexyContent_Templates.AppID, ToSIC_EAV_Apps.ZoneID, ToSIC_EAV_Entities.EntityGUID, ToSIC_SexyContent_ContentGroupItems.EntityID, ToSIC_SexyContent_ContentGroupItems.Temp_NewContentGroupGuid, ToSIC_SexyContent_Templates.Temp_NewTemplateGuid FROM ToSIC_SexyContent_Templates INNER JOIN ModuleSettings INNER JOIN ToSIC_SexyContent_ContentGroupItems ON ModuleSettings.SettingValue = ToSIC_SexyContent_ContentGroupItems.ContentGroupID ON ToSIC_SexyContent_Templates.TemplateID = ToSIC_SexyContent_ContentGroupItems.TemplateID INNER JOIN ToSIC_EAV_Apps ON ToSIC_SexyContent_Templates.AppID = ToSIC_EAV_Apps.AppID LEFT OUTER JOIN ToSIC_EAV_Entities ON ToSIC_SexyContent_ContentGroupItems.EntityID = ToSIC_EAV_Entities.EntityID WHERE (ToSIC_SexyContent_ContentGroupItems.SysDeleted IS NULL) AND (ModuleSettings.SettingName = N'ContentGroupID') AND ((SELECT COUNT(*) FROM ToSIC_EAV_Entities WHERE EntityGUID = ToSIC_SexyContent_ContentGroupItems.Temp_NewContentGroupGuid) = 0) ORDER BY SortOrder"; var adapterContentGroups = new SqlDataAdapter(sqlCommandContentGroups, sqlConnection); adapterContentGroups.SelectCommand.CommandTimeout = 3600; adapterContentGroups.Fill(contentGroupItemsTable); var contentGroupItems = contentGroupItemsTable.AsEnumerable().Select(c => new { ContentGroupId = (int)c["ContentGroupID"], NewContentGroupGuid = Guid.Parse((string)c["Temp_NewContentGroupGuid"]), EntityId = c["EntityID"] == DBNull.Value ? new int?() : (int)c["EntityID"], EntityGuid = c["EntityGUID"] == DBNull.Value ? (Guid?)null : ((Guid)c["EntityGUID"]), TemplateId = c["TemplateID"] == DBNull.Value ? new int?() : (int)c["TemplateID"], SortOrder = (int)c["SortOrder"], Type = (string)c["Type"], AppId = (int)c["AppID"], ZoneId = (int)c["ZoneID"], TemplateEntityGuids = new List <Guid>() { Guid.Parse((string)c["Temp_NewTemplateGuid"]) } }); var existingContentGroups = contentGroupItems.GroupBy(c => c.ContentGroupId, c => c, (id, items) => { var itemsList = items.ToList(); var contentGroup = new { NewEntityGuid = itemsList.First().NewContentGroupGuid, itemsList.First().AppId, itemsList.First().ZoneId, ContentGroupId = id, TemplateGuids = itemsList.First().TemplateEntityGuids, ContentGuids = itemsList.Where(p => p.Type == "Content").Select(p => p.EntityGuid).ToList(), PresentationGuids = itemsList.Where(p => p.Type == "Presentation").Select(p => p.EntityGuid).ToList(), ListContentGuids = itemsList.Where(p => p.Type == "ListContent").Select(p => p.EntityGuid).ToList(), ListPresentationGuids = itemsList.Where(p => p.Type == "ListPresentation").Select(p => p.EntityGuid).ToList() }; return(contentGroup); }).ToList(); #endregion // Import all entities logger.LogStep("07.00.00", "2. Import all entities", false); var apps = existingTemplates.Select(p => p.AppId).ToList(); apps.AddRange(existingContentGroups.Select(p => p.AppId)); apps = apps.Distinct().ToList(); foreach (var app in apps) { logger.LogStep("07.00.00", "Starting to migrate data for app " + app + "..."); var currentApp = app; var entitiesToImport = new List <ImportEntity>(); foreach (var t in existingTemplates.Where(t => t.AppId == currentApp)) { var entity = new ImportEntity { AttributeSetStaticName = "2SexyContent-Template", EntityGuid = t.NewEntityGuid, IsPublished = true, AssignmentObjectTypeId = ContentTypeHelpers.AssignmentObjectTypeIDDefault }; entity.Values = new Dictionary <string, List <IValueImportModel> > { { "Name", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.Name } } }, { "Path", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.Path } } }, { "ContentTypeStaticName", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.ContentTypeId } } }, { "ContentDemoEntity", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.ContentDemoEntityGuids } } }, { "PresentationTypeStaticName", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.PresentationTypeId } } }, { "PresentationDemoEntity", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.PresentationDemoEntityGuids } } }, { "ListContentTypeStaticName", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.ListContentTypeId } } }, { "ListContentDemoEntity", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.ListContentDemoEntityGuids } } }, { "ListPresentationTypeStaticName", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.ListPresentationTypeId } } }, { "ListPresentationDemoEntity", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.ListPresentationDemoEntityGuids } } }, { "Type", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.Type } } }, { "IsHidden", new List <IValueImportModel> { new ValueImportModel <bool?>(entity) { Value = t.IsHidden } } }, { "Location", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.Location } } }, { "UseForList", new List <IValueImportModel> { new ValueImportModel <bool?>(entity) { Value = t.UseForList } } }, { "PublishData", new List <IValueImportModel> { new ValueImportModel <bool?>(entity) { Value = t.PublishData } } }, { "StreamsToPublish", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.StreamsToPublish } } }, { "Pipeline", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.PipelineEntityGuids } } }, { "ViewNameInUrl", new List <IValueImportModel> { new ValueImportModel <string>(entity) { Value = t.ViewNameInUrl } } } }; entitiesToImport.Add(entity); } foreach (var t in existingContentGroups.Where(t => t.AppId == app)) { var entity = new ImportEntity { AttributeSetStaticName = "2SexyContent-ContentGroup", EntityGuid = t.NewEntityGuid, IsPublished = true, AssignmentObjectTypeId = ContentTypeHelpers.AssignmentObjectTypeIDDefault }; entity.Values = new Dictionary <string, List <IValueImportModel> > { { "Template", new List <IValueImportModel> { new ValueImportModel <List <Guid> >(entity) { Value = t.TemplateGuids } } }, { "Content", new List <IValueImportModel> { new ValueImportModel <List <Guid?> >(entity) { Value = t.ContentGuids } } }, { "Presentation", new List <IValueImportModel> { new ValueImportModel <List <Guid?> >(entity) { Value = t.PresentationGuids } } }, { "ListContent", new List <IValueImportModel> { new ValueImportModel <List <Guid?> >(entity) { Value = t.ListContentGuids } } }, { "ListPresentation", new List <IValueImportModel> { new ValueImportModel <List <Guid?> >(entity) { Value = t.ListPresentationGuids } } } }; entitiesToImport.Add(entity); } var import = new Eav.Import.Import(null, app, userName); import.RunImport(null, entitiesToImport); logger.LogStep("07.00.00", "Migrated data for app " + app); } logger.LogStep("07.00.00", "Done", false); }
public static void Import(this Import.ImportEntity importEntity, int zoneId, int appId, string userName) { var import = new Eav.Import.Import(zoneId, appId, userName, false); import.RunImport(null, new[] { importEntity }); }
/// <summary> /// Add ContentTypes for ContentGroup and move all 2sxc data to EAV /// </summary> internal void Version070000() { logger.LogStep("07.00.00", "Start", false); var userName = "******"; #region 1. Import new ContentTypes for ContentGroups and Templates logger.LogStep("07.00.00", "1. Import new ContentTypes for ContentGroups and Templates", false); if (DataSource.GetCache(Constants.DefaultZoneId, Constants.MetaDataAppId).GetContentType("2SexyContent-Template") == null) { var xmlToImport = File.ReadAllText(HttpContext.Current.Server.MapPath("~/DesktopModules/ToSIC_SexyContent/Upgrade/07.00.00.xml")); //var xmlToImport = File.ReadAllText("../../../../Upgrade/07.00.00.xml"); var xmlImport = new XmlImport("en-US", userName, true); var success = xmlImport.ImportXml(Constants.DefaultZoneId, Constants.MetaDataAppId, XDocument.Parse(xmlToImport)); if (!success) { var messages = String.Join("\r\n- ", xmlImport.ImportLog.Select(p => p.Message).ToArray()); throw new Exception("The 2sxc module upgrade to 07.00.00 failed: " + messages); } } #endregion // 2. Move all existing data to the new ContentTypes - Append new IDs to old data (ensures that we can fix things that went wrong after upgrading the module) #region Prepare Templates logger.LogStep("07.00.00", "2. Move all existing data to the new ContentTypes - Append new IDs to old data (ensures that we can fix things that went wrong after upgrading the module)", false); var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["SiteSqlServer"].ConnectionString); var templates = new DataTable(); const string sqlCommand = @"SELECT ToSIC_SexyContent_Templates.TemplateID, ToSIC_SexyContent_Templates.PortalID, ToSIC_SexyContent_Templates.Name, ToSIC_SexyContent_Templates.Path, ToSIC_SexyContent_Templates.AttributeSetID, ToSIC_SexyContent_Templates.DemoEntityID, ToSIC_SexyContent_Templates.Script, ToSIC_SexyContent_Templates.IsFile, ToSIC_SexyContent_Templates.Type, ToSIC_SexyContent_Templates.IsHidden, ToSIC_SexyContent_Templates.Location, ToSIC_SexyContent_Templates.UseForList, ToSIC_SexyContent_Templates.UseForItem, ToSIC_SexyContent_Templates.SysCreated, ToSIC_SexyContent_Templates.SysCreatedBy, ToSIC_SexyContent_Templates.SysModified, ToSIC_SexyContent_Templates.SysModifiedBy, ToSIC_SexyContent_Templates.SysDeleted, ToSIC_SexyContent_Templates.SysDeletedBy, ToSIC_SexyContent_Templates.AppID, ToSIC_SexyContent_Templates.PublishData, ToSIC_SexyContent_Templates.StreamsToPublish, ToSIC_SexyContent_Templates.PipelineEntityID, ToSIC_SexyContent_Templates.ViewNameInUrl, ToSIC_SexyContent_Templates.Temp_PresentationTypeID, ToSIC_SexyContent_Templates.Temp_PresentationDemoEntityID, ToSIC_SexyContent_Templates.Temp_ListContentTypeID, ToSIC_SexyContent_Templates.Temp_ListContentDemoEntityID, ToSIC_SexyContent_Templates.Temp_ListPresentationTypeID, ToSIC_SexyContent_Templates.Temp_ListPresentationDemoEntityID, ToSIC_SexyContent_Templates.Temp_NewTemplateGuid, ToSIC_EAV_Apps.ZoneID, ToSIC_EAV_Entities_1.EntityGUID AS ContentDemoEntityGuid, ToSIC_EAV_Entities_2.EntityGUID AS PresentationDemoEntityGuid, ToSIC_EAV_Entities_3.EntityGUID AS ListContentDemoEntityGuid, ToSIC_EAV_Entities_4.EntityGUID AS ListPresentationDemoEntityGuid, ToSIC_EAV_Entities.EntityGUID AS PipelineEntityGuid FROM ToSIC_SexyContent_Templates INNER JOIN ToSIC_EAV_Apps ON ToSIC_SexyContent_Templates.AppID = ToSIC_EAV_Apps.AppID LEFT OUTER JOIN ToSIC_EAV_Entities ON ToSIC_SexyContent_Templates.PipelineEntityID = ToSIC_EAV_Entities.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_3 ON ToSIC_SexyContent_Templates.Temp_ListContentDemoEntityID = ToSIC_EAV_Entities_3.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_1 ON ToSIC_SexyContent_Templates.DemoEntityID = ToSIC_EAV_Entities_1.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_2 ON ToSIC_SexyContent_Templates.Temp_PresentationDemoEntityID = ToSIC_EAV_Entities_2.EntityID LEFT OUTER JOIN ToSIC_EAV_Entities AS ToSIC_EAV_Entities_4 ON ToSIC_SexyContent_Templates.Temp_ListPresentationDemoEntityID = ToSIC_EAV_Entities_4.EntityID WHERE (ToSIC_SexyContent_Templates.SysDeleted IS NULL) AND ((SELECT COUNT(*) FROM ToSIC_EAV_Entities WHERE EntityGUID = ToSIC_SexyContent_Templates.Temp_NewTemplateGuid) = 0)"; var adapter = new SqlDataAdapter(sqlCommand, sqlConnection); adapter.SelectCommand.CommandTimeout = 3600; adapter.Fill(templates); var existingTemplates = templates.AsEnumerable().Select(t => { var templateId = (int)t["TemplateID"]; var zoneId = (int)t["ZoneID"]; var appId = (int)t["AppID"]; var cache = ((BaseCache)DataSource.GetCache(zoneId, appId)).GetContentTypes(); #region Helper Functions Func<int?, string> getContentTypeStaticName = contentTypeId => { if (!contentTypeId.HasValue || contentTypeId == 0) return ""; if (cache.Any(c => c.Value.AttributeSetId == contentTypeId)) return cache[contentTypeId.Value].StaticName; return ""; }; #endregion // Create anonymous object to validate the types var tempTemplate = new { TemplateID = templateId, Name = (string)t["Name"], Path = (string)t["Path"], NewEntityGuid = Guid.Parse((string)t["Temp_NewTemplateGuid"]), //AlreadyImported = t["Temp_NewTemplateGuid"] != DBNull.Value, ContentTypeId = getContentTypeStaticName(t["AttributeSetID"] == DBNull.Value ? new int?() : (int)t["AttributeSetID"]), ContentDemoEntityGuids = t["ContentDemoEntityGuid"] == DBNull.Value ? new List<Guid>() : new List<Guid> { (Guid)t["ContentDemoEntityGuid"] }, PresentationTypeId = getContentTypeStaticName((int)t["Temp_PresentationTypeID"]), PresentationDemoEntityGuids = t["PresentationDemoEntityGuid"] == DBNull.Value ? new List<Guid>() : new List<Guid> { (Guid)t["PresentationDemoEntityGuid"] }, ListContentTypeId = getContentTypeStaticName((int)t["Temp_ListContentTypeID"]), ListContentDemoEntityGuids = t["ListContentDemoEntityGuid"] == DBNull.Value ? new List<Guid>() : new List<Guid> { (Guid)t["ListContentDemoEntityGuid"] }, ListPresentationTypeId = getContentTypeStaticName((int)t["Temp_ListPresentationTypeID"]), ListPresentationDemoEntityGuids = t["ListPresentationDemoEntityGuid"] == DBNull.Value ? new List<Guid>() : new List<Guid> { (Guid)t["ListPresentationDemoEntityGuid"] }, Type = (string)t["Type"], IsHidden = (bool)t["IsHidden"], Location = (string)t["Location"], UseForList = (bool)t["UseForList"], AppId = appId, PublishData = (bool)t["PublishData"], StreamsToPublish = (string)t["StreamsToPublish"], PipelineEntityGuids = t["PipelineEntityGuid"] == DBNull.Value ? new List<Guid>() : new List<Guid> { (Guid)t["PipelineEntityGuid"] }, ViewNameInUrl = t["ViewNameInUrl"].ToString(), ZoneId = zoneId }; return tempTemplate; }).ToList(); #endregion #region Prepare ContentGroups logger.LogStep("07.00.00", "2. Prepare Content Groups", false); var contentGroupItemsTable = new DataTable(); const string sqlCommandContentGroups = @"SELECT DISTINCT ToSIC_SexyContent_ContentGroupItems.ContentGroupItemID, ToSIC_SexyContent_ContentGroupItems.ContentGroupID, ToSIC_SexyContent_ContentGroupItems.TemplateID, ToSIC_SexyContent_ContentGroupItems.SortOrder, ToSIC_SexyContent_ContentGroupItems.Type, ToSIC_SexyContent_ContentGroupItems.SysCreated, ToSIC_SexyContent_ContentGroupItems.SysCreatedBy, ToSIC_SexyContent_ContentGroupItems.SysModified, ToSIC_SexyContent_ContentGroupItems.SysModifiedBy, ToSIC_SexyContent_ContentGroupItems.SysDeleted, ToSIC_SexyContent_ContentGroupItems.SysDeletedBy, ToSIC_SexyContent_Templates.AppID, ToSIC_EAV_Apps.ZoneID, ToSIC_EAV_Entities.EntityGUID, ToSIC_SexyContent_ContentGroupItems.EntityID, ToSIC_SexyContent_ContentGroupItems.Temp_NewContentGroupGuid, ToSIC_SexyContent_Templates.Temp_NewTemplateGuid FROM ToSIC_SexyContent_Templates INNER JOIN ModuleSettings INNER JOIN ToSIC_SexyContent_ContentGroupItems ON ModuleSettings.SettingValue = ToSIC_SexyContent_ContentGroupItems.ContentGroupID ON ToSIC_SexyContent_Templates.TemplateID = ToSIC_SexyContent_ContentGroupItems.TemplateID INNER JOIN ToSIC_EAV_Apps ON ToSIC_SexyContent_Templates.AppID = ToSIC_EAV_Apps.AppID LEFT OUTER JOIN ToSIC_EAV_Entities ON ToSIC_SexyContent_ContentGroupItems.EntityID = ToSIC_EAV_Entities.EntityID WHERE (ToSIC_SexyContent_ContentGroupItems.SysDeleted IS NULL) AND (ModuleSettings.SettingName = N'ContentGroupID') AND ((SELECT COUNT(*) FROM ToSIC_EAV_Entities WHERE EntityGUID = ToSIC_SexyContent_ContentGroupItems.Temp_NewContentGroupGuid) = 0) ORDER BY SortOrder"; var adapterContentGroups = new SqlDataAdapter(sqlCommandContentGroups, sqlConnection); adapterContentGroups.SelectCommand.CommandTimeout = 3600; adapterContentGroups.Fill(contentGroupItemsTable); var contentGroupItems = contentGroupItemsTable.AsEnumerable().Select(c => new { ContentGroupId = (int)c["ContentGroupID"], NewContentGroupGuid = Guid.Parse((string)c["Temp_NewContentGroupGuid"]), EntityId = c["EntityID"] == DBNull.Value ? new int?() : (int)c["EntityID"], EntityGuid = c["EntityGUID"] == DBNull.Value ? (Guid?)null : ((Guid)c["EntityGUID"]), TemplateId = c["TemplateID"] == DBNull.Value ? new int?() : (int)c["TemplateID"], SortOrder = (int)c["SortOrder"], Type = (string)c["Type"], AppId = (int)c["AppID"], ZoneId = (int)c["ZoneID"], TemplateEntityGuids = new List<Guid>() { Guid.Parse((string)c["Temp_NewTemplateGuid"]) } }); var existingContentGroups = contentGroupItems.GroupBy(c => c.ContentGroupId, c => c, (id, items) => { var itemsList = items.ToList(); var contentGroup = new { NewEntityGuid = itemsList.First().NewContentGroupGuid, itemsList.First().AppId, itemsList.First().ZoneId, ContentGroupId = id, TemplateGuids = itemsList.First().TemplateEntityGuids, ContentGuids = itemsList.Where(p => p.Type == Constants.ContentKey).Select(p => p.EntityGuid).ToList(), PresentationGuids = itemsList.Where(p => p.Type == Constants.PresentationKey).Select(p => p.EntityGuid).ToList(), ListContentGuids = itemsList.Where(p => p.Type == "ListContent").Select(p => p.EntityGuid).ToList(), ListPresentationGuids = itemsList.Where(p => p.Type == "ListPresentation").Select(p => p.EntityGuid).ToList() }; return contentGroup; }).ToList(); #endregion // Import all entities logger.LogStep("07.00.00", "2. Import all entities", false); var apps = existingTemplates.Select(p => p.AppId).ToList(); apps.AddRange(existingContentGroups.Select(p => p.AppId)); apps = apps.Distinct().ToList(); foreach (var app in apps) { logger.LogStep("07.00.00", "Starting to migrate data for app " + app + "..."); var currentApp = app; var entitiesToImport = new List<ImportEntity>(); foreach (var t in existingTemplates.Where(t => t.AppId == currentApp)) { var entity = new ImportEntity { AttributeSetStaticName = "2SexyContent-Template", EntityGuid = t.NewEntityGuid, IsPublished = true, AssignmentObjectTypeId = ContentTypeHelpers.AssignmentObjectTypeIDDefault }; entity.Values = new Dictionary<string, List<IValueImportModel>> { {"Name", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.Name }}}, {"Path", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.Path }}}, {"ContentTypeStaticName", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.ContentTypeId }}}, {"ContentDemoEntity", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.ContentDemoEntityGuids }}}, {"PresentationTypeStaticName", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.PresentationTypeId }}}, {"PresentationDemoEntity", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.PresentationDemoEntityGuids }}}, {"ListContentTypeStaticName", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.ListContentTypeId }}}, {"ListContentDemoEntity", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.ListContentDemoEntityGuids }}}, {"ListPresentationTypeStaticName", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.ListPresentationTypeId }}}, {"ListPresentationDemoEntity", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.ListPresentationDemoEntityGuids }}}, {"Type", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.Type }}}, {"IsHidden", new List<IValueImportModel> {new ValueImportModel<bool?>(entity) { Value = t.IsHidden }}}, {"Location", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.Location }}}, {"UseForList", new List<IValueImportModel> {new ValueImportModel<bool?>(entity) { Value = t.UseForList }}}, {"PublishData", new List<IValueImportModel> {new ValueImportModel<bool?>(entity) { Value = t.PublishData }}}, {"StreamsToPublish", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.StreamsToPublish }}}, {"Pipeline", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.PipelineEntityGuids }}}, {"ViewNameInUrl", new List<IValueImportModel> {new ValueImportModel<string>(entity) { Value = t.ViewNameInUrl }}} }; entitiesToImport.Add(entity); } foreach (var t in existingContentGroups.Where(t => t.AppId == app)) { var entity = new ImportEntity { AttributeSetStaticName = "2SexyContent-ContentGroup", EntityGuid = t.NewEntityGuid, IsPublished = true, AssignmentObjectTypeId = ContentTypeHelpers.AssignmentObjectTypeIDDefault }; entity.Values = new Dictionary<string, List<IValueImportModel>> { {"Template", new List<IValueImportModel> {new ValueImportModel<List<Guid>>(entity) { Value = t.TemplateGuids }}}, {Constants.ContentKey, new List<IValueImportModel> {new ValueImportModel<List<Guid?>>(entity) { Value = t.ContentGuids }}}, {Constants.PresentationKey, new List<IValueImportModel> {new ValueImportModel<List<Guid?>>(entity) { Value = t.PresentationGuids }}}, {"ListContent", new List<IValueImportModel> {new ValueImportModel<List<Guid?>>(entity) { Value = t.ListContentGuids }}}, {"ListPresentation", new List<IValueImportModel> {new ValueImportModel<List<Guid?>>(entity) { Value = t.ListPresentationGuids }}} }; entitiesToImport.Add(entity); } var import = new Eav.Import.Import(null, app, userName); import.RunImport(null, entitiesToImport); logger.LogStep("07.00.00", "Migrated data for app " + app); } logger.LogStep("07.00.00", "Done", false); }
/// <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> private static void EnsurePipelineDesignerAttributeSets() { // 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 Eav.Import.Import(Constants.DefaultZoneId, Constants.MetaDataAppId, SexyContent.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(SexyContent.InternalUserName); eavVersionUpgrade.EnsurePipelineDesignerAttributeSets(); }