/// <summary> /// Get a Root CMS Block if you have the ModuleInfo object. /// </summary> /// <param name="container"></param> /// <param name="parentLog">optional logger to attach to</param> /// <returns>An initialized CMS Block, ready to use/render</returns> public static IBlockBuilder CmsBlock(IContainer container, ILog parentLog = null) { var dnnModule = ((Container <ModuleInfo>)container).UnwrappedContents; var tenant = new DnnTenant(new PortalSettings(dnnModule.OwnerPortalID)); return(new BlockFromModule().Init(new DnnContext(tenant, container, new DnnUser()), parentLog).BlockBuilder); }
private Tuple <App, PermissionCheckBase> AppAndPermissionChecker(int appId, string typeName) { var env = Factory.Resolve <IEnvironmentFactory>().Environment(Log); var tenant = new DnnTenant(PortalSettings.Current); var uiZoneId = env.ZoneMapper.GetZoneId(tenant.Id); // now do relevant security checks var zoneId = SystemManager.ZoneIdOfApp(appId); var app = new App(tenant, zoneId, appId, parentLog: Log); var type = typeName == null ? null : new AppRuntime(zoneId, appId, Log) .ContentTypes.Get(typeName); var samePortal = uiZoneId == tenant.Id; var portalToUseInSecCheck = samePortal ? PortalSettings.Current : null; // user has edit permissions on this app, and it's the same app as the user is coming from var checker = new DnnPermissionCheck(Log, instance: SxcInstance.EnvInstance, app: app, portal: portalToUseInSecCheck, targetType: type); return(new Tuple <App, PermissionCheckBase>(app, checker)); }
public IEnumerable <AppUiInfo> GetSelectableApps(string apps = null) { // Note: we must get the zone-id from the tenant, since the app may not yet exist when inserted the first time var tenant = new DnnTenant(PortalSettings); return(new CmsZones(tenant.ZoneId, Log).AppsRt.GetSelectableApps(tenant, apps).ToList()); }
private void PrepCore(App app, Guid entityGuid, string fieldName, bool usePortalRoot) { var tenant = new DnnTenant(Dnn.Portal); AdamAppContext = new AdamAppContext(tenant, app, SxcInstance); ContainerContext = usePortalRoot ? new ContainerOfTenant(AdamAppContext) as ContainerBase : new ContainerOfField(AdamAppContext, entityGuid, fieldName); }
private void PrepCore(IApp app, Guid entityGuid, string fieldName, bool usePortalRoot) { Log.Add("PrepCore(...)"); var dnn = new DnnContext(BlockBuilder?.Container); var tenant = new DnnTenant(dnn.Portal); AdamAppContext = new AdamAppContext(tenant, app, BlockBuilder, 10, Log); ContainerContext = usePortalRoot ? new ContainerOfTenant(AdamAppContext) as ContainerBase : new ContainerOfField(AdamAppContext, entityGuid, fieldName); }
private void PrepCore(App app, Guid entityGuid, string fieldName, bool usePortalRoot) { Log.Add("PrepCore(...)"); var dnn = new DnnHelper(SxcInstance?.EnvInstance); var tenant = new DnnTenant(dnn.Portal); AdamAppContext = new AdamAppContext(tenant, app, SxcInstance, Log); ContainerContext = usePortalRoot ? new ContainerOfTenant(AdamAppContext) as ContainerBase : new ContainerOfField(AdamAppContext, entityGuid, fieldName); }
public override XmlExporter Init(int zoneId, int appId, AppRuntime appRuntime, bool appExport, string[] attrSetIds, string[] entityIds, Log parentLog) { var tenant = new DnnTenant(PortalSettings.Current); var app = new App(tenant, zoneId, appId); AdamAppContext = new AdamAppContext(tenant, app, null); Constructor(zoneId, appRuntime, app.AppGuid, appExport, attrSetIds, entityIds, parentLog); // this must happen very early, to ensure that the file-lists etc. are correct for exporting when used externally InitExportXDocument(PortalSettings.Current.DefaultLanguage, Settings.ModuleVersion); return(this); }
protected MultiPermissionsApp(IBlockBuilder blockBuilder, int zoneId, int appId, ILog parentLog) : base("Api.Perms", parentLog) { var wrapLog = Log.Call($"..., appId: {appId}, ..."); BlockBuilder = blockBuilder; var tenant = new DnnTenant(PortalSettings.Current); var environment = Factory.Resolve <IEnvironmentFactory>().Environment(Log); var contextZoneId = environment.ZoneMapper.GetZoneId(tenant.Id); App = new App(tenant, zoneId, appId, ConfigurationProvider.Build(blockBuilder, true), false, Log); SamePortal = contextZoneId == zoneId; PortalForSecurityCheck = SamePortal ? PortalSettings.Current : null; wrapLog($"ready for z/a:{zoneId}/{appId} t/z:{tenant.Id}/{contextZoneId} same:{SamePortal}"); }
public dynamic Apps(int zoneId) { var cms = new CmsZones(zoneId, Env, Log); var tenant = new DnnTenant(new PortalSettings(ActiveModule.OwnerPortalID)); var configurationBuilder = ConfigurationProvider.Build(BlockBuilder, true); var list = cms.AppsRt.GetApps(tenant, configurationBuilder); return(list.Select(a => new { Id = a.AppId, IsApp = a.AppGuid != Eav.Constants.DefaultAppName, Guid = a.AppGuid, a.Name, a.Folder, AppRoot = a.Path, IsHidden = a.Hidden, ConfigurationId = a.Configuration?.Id, Items = a.Data.List.Count(), a.Thumbnail, Version = a.VersionSafe() }).ToList()); }
public IEnumerable <AppUiInfo> GetSelectableApps(string apps = null) { // we must get the zone-id from the environment, // since the app may not yet exist when inserted the first time var tenant = new DnnTenant(PortalSettings.Current); var tenantZoneId = Env.ZoneMapper.GetZoneId(tenant); var list = new CmsZones(tenantZoneId, Env, Log).AppsRt.GetSelectableApps(tenant).ToList(); if (string.IsNullOrWhiteSpace(apps)) { return(list); } // New feature in 10.27 - if app-list is provided, only return these var appNames = apps.Split(',') .Select(s => s.Trim()) .Where(s => !string.IsNullOrWhiteSpace(s)) .ToList(); list = list.Where(ap => appNames .Any(name => string.Equals(name, ap.Name, StringComparison.InvariantCultureIgnoreCase))) .ToList(); return(list); }
public void Publish(int instanceId, int version) { Log.Add($"Publish(m:{instanceId}, v:{version})"); try { // publish all entites of this content block var dnnModule = ModuleController.Instance.GetModule(instanceId, Null.NullInteger, true); var instanceInfo = new DnnContainer(dnnModule); // must find tenant through module, as the PortalSettings.Current is null in search mode var tenant = new DnnTenant(new PortalSettings(dnnModule.OwnerPortalID)); var cb = new BlockFromModule(instanceInfo, Log, tenant); Log.Add($"found dnn mod {instanceInfo.Id}, tenant {tenant.Id}, cb exists: {cb.ContentGroupExists}"); if (cb.ContentGroupExists) { Log.Add("cb exists"); var appManager = new AppManager(cb /*.AppId*/, Log); // Add content entities IEnumerable <IEntity> list = new List <IEntity>(); list = TryToAddStream(list, cb.Data, Constants.DefaultStreamName); list = TryToAddStream(list, cb.Data, "ListContent"); list = TryToAddStream(list, cb.Data, "PartOfPage"); // ReSharper disable PossibleMultipleEnumeration // Find related presentation entities var attachedPresItems = list .Where(e => (e as EntityInBlock)?.Presentation != null) .Select(e => ((EntityInBlock)e).Presentation); Log.Add($"adding presentation item⋮{attachedPresItems.Count()}"); list = list.Concat(attachedPresItems); // ReSharper restore PossibleMultipleEnumeration var ids = list.Where(e => !e.IsPublished).Select(e => e.EntityId).ToList(); // publish BlockConfiguration as well - if there already is one if (cb.Configuration != null) { Log.Add($"add group id:{cb.Configuration.Id}"); ids.Add(cb.Configuration.Id); } Log.Add(() => $"will publish id⋮{ids.Count} ids:[{ string.Join(",", ids.Select(i => i.ToString()).ToArray()) }]"); if (ids.Any()) { appManager.Entities.Publish(ids.ToArray()); } else { Log.Add("no ids found, won\'t publish items"); } } // Set published version new PagePublishing.ModuleVersions(instanceId, Log).PublishLatestVersion(); Log.Add("publish completed"); } catch (Exception ex) { DnnLogging.LogToDnn("exception", "publishing", Log, force: true); DotNetNuke.Services.Exceptions.Exceptions.LogException(ex); throw; } }
/// <summary> /// Get search info for each dnn module containing 2sxc data /// </summary> /// <returns></returns> public IList <SearchDocument> GetModifiedSearchDocuments(IInstanceInfo instance, DateTime beginDate) { var searchDocuments = new List <SearchDocument>(); var dnnModule = (instance as EnvironmentInstance <ModuleInfo>)?.Original; // always log with method, to ensure errors are cought Log.Add($"start search for mod#{dnnModule?.ModuleID}"); History.Add("dnn-search", Log); if (dnnModule == null) { return(searchDocuments); } var isContentModule = dnnModule.DesktopModule.ModuleName == "2sxc"; // New Context because PortalSettings.Current is null var zoneId = new DnnEnvironment(Log).ZoneMapper.GetZoneId(dnnModule.OwnerPortalID); var appId = !isContentModule ? new DnnMapAppToInstance(Log).GetAppIdFromInstance(instance, zoneId) : new ZoneRuntime(zoneId, Log).DefaultAppId; if (!appId.HasValue) { return(searchDocuments); } // As PortalSettings.Current is null, instanciate with modules' portal id var portalSettings = new PortalSettings(dnnModule.OwnerPortalID); // Ensure cache builds up with correct primary language var cache = Eav.Factory.Resolve <ICache>(); ((BaseCache)cache).ZoneId = zoneId; ((BaseCache)cache).AppId = appId.Value; cache.PreLoadCache(portalSettings.DefaultLanguage.ToLower()); // must find tenant through module, as the PortalSettings.Current is null in search mode var tenant = new DnnTenant(portalSettings); var mcb = new ModuleContentBlock(instance, Log, tenant); var sexy = mcb.SxcInstance; var language = dnnModule.CultureCode; var contentGroup = sexy.App.ContentGroupManager.GetInstanceContentGroup(dnnModule.ModuleID, dnnModule.TabID); var template = contentGroup.Template; // This list will hold all EAV entities to be indexed var dataSource = sexy.Data; if (template == null) { return(searchDocuments); } var engine = EngineFactory.CreateEngine(template); engine.Init(template, sexy.App, new DnnInstanceInfo(dnnModule), dataSource, InstancePurposes.IndexingForSearch, sexy, Log); // see if data customization inside the cshtml works try { engine.CustomizeData(); } catch (Exception e) // Catch errors here, because of references to Request etc. { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } var searchInfoDictionary = new Dictionary <string, List <ISearchInfo> >(); // Get DNN SearchDocuments from 2Sexy SearchInfos foreach (var stream in dataSource.Out.Where(p => p.Key != AppConstants.Presentation && p.Key != AppConstants.ListPresentation)) { var entities = stream.Value.List; var searchInfoList = searchInfoDictionary[stream.Key] = new List <ISearchInfo>(); searchInfoList.AddRange(entities.Select(entity => { var searchInfo = new SearchInfo { Entity = entity, Url = "", Description = "", Body = GetJoinedAttributes(entity, language), Title = entity.Title?[language]?.ToString() ?? "(no title)", ModifiedTimeUtc = (entity.Modified == DateTime.MinValue ? DateTime.Now.Date.AddHours(DateTime.Now.Hour) : entity.Modified).ToUniversalTime(), UniqueKey = "2sxc-" + dnnModule.ModuleID + "-" + (entity.EntityGuid != new Guid() ? entity.EntityGuid.ToString() : (stream.Key + "-" + entity.EntityId)), IsActive = true, TabId = dnnModule.TabID, PortalId = dnnModule.PortalID }; // Take the newest value (from ContentGroupItem and Entity) if (entity is IHasEditingData typed) { var contentGroupItemModifiedUtc = typed.ContentGroupItemModified.ToUniversalTime(); searchInfo.ModifiedTimeUtc = searchInfo.ModifiedTimeUtc > contentGroupItemModifiedUtc ? searchInfo.ModifiedTimeUtc : contentGroupItemModifiedUtc; } return(searchInfo); })); } // check if the cshtml has search customizations try { engine.CustomizeSearch(searchInfoDictionary, new DnnInstanceInfo(dnnModule), beginDate); } catch (Exception e) { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } // reduce load by only keeping recently modified ites foreach (var searchInfoList in searchInfoDictionary) { // Filter by Date - take only SearchDocuments that changed since beginDate var searchDocumentsToAdd = searchInfoList.Value.Where(p => p.ModifiedTimeUtc >= beginDate.ToUniversalTime()).Select(p => (SearchDocument)p); searchDocuments.AddRange(searchDocumentsToAdd); } return(searchDocuments); }
/// <summary> /// Get search info for each dnn module containing 2sxc data /// </summary> /// <returns></returns> public IList <SearchDocument> GetModifiedSearchDocuments(IContainer container, DateTime beginDate) { var searchDocuments = new List <SearchDocument>(); var dnnModule = (container as Container <ModuleInfo>)?.UnwrappedContents; // always log with method, to ensure errors are caught Log.Add($"start search for mod#{dnnModule?.ModuleID}"); // turn off logging into history by default - the template code can reactivate this if desired Log.Preserve = false; if (dnnModule == null) { return(searchDocuments); } // New Context because Portal-Settings.Current is null var appId = container.BlockIdentifier.AppId; if (appId == AppConstants.AppIdNotFound || appId == Eav.Constants.NullId) { return(searchDocuments); } // Since Portal-Settings.Current is null, instantiate with modules' portal id (which can be a different portal!) var portalSettings = new PortalSettings(dnnModule.OwnerPortalID); var tenant = new DnnTenant(portalSettings); // Ensure cache builds up with correct primary language var cache = State.Cache; cache.Load(container.BlockIdentifier, tenant.DefaultLanguage); var modBlock = new BlockFromModule().Init(new DnnContext(tenant, container, new DnnUser()), Log); var language = dnnModule.CultureCode; var view = modBlock.View; if (view == null) { return(searchDocuments); } // This list will hold all EAV entities to be indexed var dataSource = modBlock.Data; // 2020-03-12 Try to attach DNN Lookup Providers so query-params like [DateTime:Now] or [Portal:PortalId] will work if (dataSource?.Configuration?.LookUps != null) { Log.Add("Will try to attach dnn providers to DataSource LookUps"); try { var dnnLookUps = GetDnnEngine.GenerateDnnBasedLookupEngine(portalSettings, dnnModule.ModuleID, Log); ((LookUpEngine)dataSource.Configuration.LookUps).Link(dnnLookUps); } catch (Exception e) { Log.Add("Ran into an issue with an error: " + e.Message); } } var engine = EngineFactory.CreateEngine(view); engine.Init(modBlock, Purpose.IndexingForSearch, Log); // see if data customization inside the cshtml works try { engine.CustomizeData(); } catch (Exception e) // Catch errors here, because of references to Request etc. { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } var searchInfoDictionary = new Dictionary <string, List <ISearchItem> >(); // Get DNN SearchDocuments from 2Sexy SearchInfos foreach (var stream in dataSource.Out.Where(p => p.Key != ViewParts.Presentation && p.Key != ViewParts.ListPresentation)) { var entities = stream.Value.List; var searchInfoList = searchInfoDictionary[stream.Key] = new List <ISearchItem>(); searchInfoList.AddRange(entities.Select(entity => { var searchInfo = new SearchItem { Entity = entity, Url = "", Description = "", Body = GetJoinedAttributes(entity, language), Title = entity.Title?[language]?.ToString() ?? "(no title)", ModifiedTimeUtc = (entity.Modified == DateTime.MinValue ? DateTime.Now.Date.AddHours(DateTime.Now.Hour) : entity.Modified).ToUniversalTime(), UniqueKey = "2sxc-" + dnnModule.ModuleID + "-" + (entity.EntityGuid != new Guid() ? entity.EntityGuid.ToString() : (stream.Key + "-" + entity.EntityId)), IsActive = true, TabId = dnnModule.TabID, PortalId = dnnModule.PortalID }; return(searchInfo); })); } // check if the cshtml has search customizations try { engine.CustomizeSearch(searchInfoDictionary, new DnnContainer().Init(dnnModule, Log), beginDate); } catch (Exception e) { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } // add it to insights / history. It will only be preserved, if the inner code ran a Log.Preserve = true; History.Add("dnn-search", Log); // reduce load by only keeping recently modified items foreach (var searchInfoList in searchInfoDictionary) { // Filter by Date - take only SearchDocuments that changed since beginDate var searchDocumentsToAdd = searchInfoList.Value.Where(p => p.ModifiedTimeUtc >= beginDate.ToUniversalTime()).Select(p => (SearchDocument)p); searchDocuments.AddRange(searchDocumentsToAdd); } return(searchDocuments); }
/// <summary> /// Get search info for each dnn module containing 2sxc data /// </summary> /// <returns></returns> public IList <SearchDocument> GetModifiedSearchDocuments(IContainer container, DateTime beginDate) { var searchDocuments = new List <SearchDocument>(); var dnnModule = (container as Container <ModuleInfo>)?.UnwrappedContents; // always log with method, to ensure errors are caught Log.Add($"start search for mod#{dnnModule?.ModuleID}"); // turn off logging into history by default - the template code can reactivate this if desired Log.Preserve = false; if (dnnModule == null) { return(searchDocuments); } var isContentModule = dnnModule.DesktopModule.ModuleName == "2sxc"; // New Context because PortalSettings.Current is null var zoneId = new DnnEnvironment(Log).ZoneMapper.GetZoneId(dnnModule.OwnerPortalID); var appId = !isContentModule ? new DnnMapAppToInstance(Log).GetAppIdFromInstance(container, zoneId) : new ZoneRuntime(zoneId, Log).DefaultAppId; if (!appId.HasValue) { return(searchDocuments); } // As PortalSettings.Current is null, instantiate with modules' portal id var portalSettings = new PortalSettings(dnnModule.OwnerPortalID); // Ensure cache builds up with correct primary language var cache = State.Cache; cache.Load(new AppIdentity(zoneId, appId.Value), portalSettings.DefaultLanguage.ToLower()); // must find tenant through module, as the PortalSettings.Current is null in search mode var tenant = new DnnTenant(portalSettings); var mcb = new BlockFromModule(container, Log, tenant); var cmsBlock = mcb.BlockBuilder; var language = dnnModule.CultureCode; var view = cmsBlock.View; if (view == null) { return(searchDocuments); } // This list will hold all EAV entities to be indexed var dataSource = cmsBlock.Block.Data; // 2020-03-12 Try to attach DNN Lookup Providers so query-params like [DateTime:Now] or [Portal:PortalId] will work if (dataSource?.Configuration?.LookUps != null) { Log.Add("Will try to attach dnn providers to DataSource LookUps"); try { //var provider = dataSource.Configuration.LookUps; var dnnLookUps = GetDnnEngine.GenerateDnnBasedLookupEngine(portalSettings, dnnModule.ModuleID, Log); ((LookUpEngine)dataSource.Configuration.LookUps).Link(dnnLookUps); // .Sources; //Log.Add($"Environment provided {dnnLookUps.Count} sources"); //foreach (var prov in dnnLookUps) // if (!provider.Sources.ContainsKey(prov.Key)) // provider.Sources.Add(prov.Key, prov.Value); // else // Log.Add($"Couldn't add source '{prov.Key}', as it already existed"); } catch (Exception e) { Log.Add("Ran into an issue with an error: " + e.Message); } } var engine = EngineFactory.CreateEngine(view); engine.Init(cmsBlock, Purpose.IndexingForSearch, Log); // see if data customization inside the cshtml works try { engine.CustomizeData(); } catch (Exception e) // Catch errors here, because of references to Request etc. { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } var searchInfoDictionary = new Dictionary <string, List <ISearchItem> >(); // Get DNN SearchDocuments from 2Sexy SearchInfos foreach (var stream in dataSource.Out.Where(p => p.Key != ViewParts.Presentation && p.Key != ViewParts.ListPresentation)) { var entities = stream.Value.List; var searchInfoList = searchInfoDictionary[stream.Key] = new List <ISearchItem>(); searchInfoList.AddRange(entities.Select(entity => { var searchInfo = new SearchItem { Entity = entity, Url = "", Description = "", Body = GetJoinedAttributes(entity, language), Title = entity.Title?[language]?.ToString() ?? "(no title)", ModifiedTimeUtc = (entity.Modified == DateTime.MinValue ? DateTime.Now.Date.AddHours(DateTime.Now.Hour) : entity.Modified).ToUniversalTime(), UniqueKey = "2sxc-" + dnnModule.ModuleID + "-" + (entity.EntityGuid != new Guid() ? entity.EntityGuid.ToString() : (stream.Key + "-" + entity.EntityId)), IsActive = true, TabId = dnnModule.TabID, PortalId = dnnModule.PortalID }; // CodeChange #2020-03-20#ContentGroupItemModified - Delete if no side-effects till June 2020 // 2020-03-20 2dm: unclear why this happens - the itm.Modified (above) // is identical with the typed.ContentGroupItemModified // because of this I'll turn the code off for now // I also marked 3 other code bits with the code // Take the newest value (from ContentGroupItem and Entity) //if (entity is IHasEditingData typed) //{ // var contentGroupItemModifiedUtc = typed.ContentGroupItemModified.ToUniversalTime(); // searchInfo.ModifiedTimeUtc = searchInfo.ModifiedTimeUtc > contentGroupItemModifiedUtc // ? searchInfo.ModifiedTimeUtc // : contentGroupItemModifiedUtc; //} return(searchInfo); })); } // check if the cshtml has search customizations try { engine.CustomizeSearch(searchInfoDictionary, new DnnContainer(dnnModule), beginDate); } catch (Exception e) { Exceptions.LogException(new SearchIndexException(dnnModule, e)); } // add it to insights / history. It will only be preserved, if the inner code ran a Log.Preserve = true; History.Add("dnn-search", Log); // reduce load by only keeping recently modified ites foreach (var searchInfoList in searchInfoDictionary) { // Filter by Date - take only SearchDocuments that changed since beginDate var searchDocumentsToAdd = searchInfoList.Value.Where(p => p.ModifiedTimeUtc >= beginDate.ToUniversalTime()).Select(p => (SearchDocument)p); searchDocuments.AddRange(searchDocumentsToAdd); } return(searchDocuments); }