public IBlock CreateBlock(int zoneId, int pageId, int containerId, int appId, Guid blockGuid, ILog log) { var context = CreateContext(zoneId, pageId, containerId, appId, blockGuid); var block = new BlockFromModule().Init(context, log); return(block); }
protected IBlock GetBlock(bool allowNoContextFound = true) { var wrapLog = Log.Call <IBlock>(parameters: $"request:..., {nameof(allowNoContextFound)}: {allowNoContextFound}"); var containerId = GetTypedHeader(Sxc.WebApi.WebApiConstants.HeaderInstanceId, -1); var contentblockId = GetTypedHeader(Sxc.WebApi.WebApiConstants.HeaderContentBlockId, 0); // this can be negative, so use 0 var pageId = GetTypedHeader(Sxc.WebApi.WebApiConstants.HeaderPageId, -1); var instance = TestIds.FindInstance(containerId); if (containerId == -1 || pageId == -1 || instance == null) { if (allowNoContextFound) { return(wrapLog("not found", null)); } throw new Exception("No context found, cannot continue"); } var ctx = SxcMvc.CreateContext(HttpContext, instance.Zone, pageId, containerId, instance.App, instance.Block); IBlock block = new BlockFromModule().Init(ctx, Log); // only if it's negative, do we load the inner block if (contentblockId > 0) { return(wrapLog("found", block)); } Log.Add($"Inner Content: {contentblockId}"); block = new BlockFromEntity().Init(block, contentblockId, Log); return(wrapLog("found", block)); }
internal static IBlock GetCmsBlock(HttpRequestMessage request, bool allowNoContextFound, ILog log) { var wrapLog = log.Call <IBlock>(parameters: $"request:..., {nameof(allowNoContextFound)}: {allowNoContextFound}"); //const string headerId = "ContentBlockId"; var moduleInfo = request.FindModuleInfo(); if (allowNoContextFound & moduleInfo == null) { return(wrapLog("request ModuleInfo not found, allowed", null)); } if (moduleInfo == null) { log.Add("context/module not found"); } var container = new DnnContainer().Init(moduleInfo, log); var tenant = moduleInfo == null ? new DnnTenant(null) : new DnnTenant().Init(moduleInfo.OwnerPortalID); var context = new DnnContext(tenant, container, new DnnUser(), GetOverrideParams(request)); IBlock block = new BlockFromModule().Init(context, log); // check if we need an inner block if (request.Headers.Contains(WebApiConstants.HeaderContentBlockId)) { var blockHeaderId = request.Headers.GetValues(WebApiConstants.HeaderContentBlockId).FirstOrDefault(); int.TryParse(blockHeaderId, out var blockId); if (blockId < 0) // negative id, so it's an inner block { log.Add($"Inner Content: {blockId}"); block = new BlockFromEntity().Init(block, blockId, log); } } return(wrapLog("ok", block)); }
internal static IBlockBuilder GetCmsBlock(HttpRequestMessage request, bool allowNoContextFound, ILog log) { var wrapLog = log.Call <IBlockBuilder>(parameters: $"request:..., {nameof(allowNoContextFound)}: {allowNoContextFound}"); const string headerId = "ContentBlockId"; var moduleInfo = request.FindModuleInfo(); if (allowNoContextFound & moduleInfo == null) { return(wrapLog("request ModuleInfo not found, allowed", null)); } if (moduleInfo == null) { log.Add("context/module not found"); } var urlParams = PrepareUrlParamsForInternalUse(request); var tenant = moduleInfo == null ? new DnnTenant(null) : new DnnTenant(new PortalSettings(moduleInfo.OwnerPortalID)); IBlock contentBlock = new BlockFromModule(new DnnContainer(moduleInfo), log, tenant, urlParams); // check if we need an inner block if (request.Headers.Contains(headerId)) { var blockHeaderId = request.Headers.GetValues(headerId).FirstOrDefault(); int.TryParse(blockHeaderId, out var blockId); if (blockId < 0) // negative id, so it's an inner block { log.Add($"Inner Content: {blockId}"); contentBlock = new BlockFromEntity(contentBlock, blockId, log); } } return(wrapLog("ok", contentBlock.BlockBuilder)); }
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(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); }