Exemplo n.º 1
0
        /// <summary>
        /// Get search info for each dnn module containing 2sxc data
        /// </summary>
        /// <returns></returns>
        public IList <SearchDocument> GetModifiedSearchDocuments(IModule module, DateTime beginDate)
        {
            var searchDocuments = new List <SearchDocument>();
            var dnnModule       = (module as Module <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 = module.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 site = new DnnSite().TrySwap(dnnModule);//.Swap(portalSettings);

            // Ensure cache builds up with correct primary language
            var cache = State.Cache;

            cache.Load(module.BlockIdentifier, site.DefaultCultureCode);

            var dnnContext = Eav.Factory.StaticBuild <IContextOfBlock>().Init(dnnModule, Log);
            var modBlock   = _serviceProvider.Build <BlockFromModule>()
                             .Init(dnnContext, Log);
            //.Init(DnnContextOfBlock.Create(site, container, Eav.Factory.GetServiceProvider()), 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?.LookUpEngine != null)
            {
                Log.Add("Will try to attach dnn providers to DataSource LookUps");
                try
                {
                    var getLookups = (DnnLookUpEngineResolver)_serviceProvider.Build <DnnLookUpEngineResolver>().Init(Log);
                    var dnnLookUps = getLookups.GenerateDnnBasedLookupEngine(site.UnwrappedContents, dnnModule.ModuleID);
                    ((LookUpEngine)dataSource.Configuration.LookUpEngine).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.Immutable;
                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,
                                       _serviceProvider.Build <DnnModule>().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);
        }
Exemplo n.º 2
0
        /// <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);
        }