Beispiel #1
0
        private int GetInstanceAppId(int zoneId)
        {
            var wrapLog = Log.Call <int>(parameters: $"{zoneId}");

            var module = UnwrappedContents ?? throw new Exception("instance is not ModuleInfo");

            var msg    = $"get appid from instance for Z:{zoneId} Mod:{module.ModuleID}";
            var zoneRt = new ZoneRuntime().Init(zoneId, Log);

            if (IsPrimary)
            {
                var appId = zoneRt.DefaultAppId;
                return(wrapLog($"{msg} - use Default app: {appId}", appId));
            }

            if (module.ModuleSettings.ContainsKey(Settings.ModuleSettingApp))
            {
                var guid  = module.ModuleSettings[Settings.ModuleSettingApp].ToString();
                var appId = zoneRt.FindAppId(guid);
                return(wrapLog($"{msg} AppG:{guid} = app:{appId}", appId));
            }

            Log.Add($"{msg} not found = null");
            return(wrapLog("not found", Eav.Constants.AppIdEmpty));
        }
        public int?GetAppIdFromInstance(IInstanceInfo instance, int zoneId)
        {
            var module = (instance as EnvironmentInstance <ModuleInfo>)?.Original
                         ?? throw new Exception("instance is not of type ModuleInfo");

            var msg = $"get appid from instance for Z:{zoneId} Mod:{module.ModuleID}";

            if (module.DesktopModule.ModuleName == "2sxc")
            {
                var appId = new ZoneRuntime(zoneId, null).DefaultAppId;
                Log.Add($"{msg} - use def app: {appId}");
                return(appId);
            }

            if (module.ModuleSettings.ContainsKey(Settings.AppNameString))
            {
                var guid  = module.ModuleSettings[Settings.AppNameString].ToString();
                var appId = AppHelpers.GetAppIdFromGuidName(zoneId, guid);
                Log.Add($"{msg} AppG:{guid} = app:{appId}");
                return(appId);
            }

            Log.Add($"{msg} not found = null");
            return(null);
        }
        public int?GetAppIdFromInstance(IContainer instance, int zoneId)
        {
            var wrapLog = Log.Call <int?>(parameters: $"..., {zoneId}");

            var module = (instance as Container <ModuleInfo>)?.UnwrappedContents
                         ?? throw new Exception("instance is not of type ModuleInfo");

            var msg = $"get appid from instance for Z:{zoneId} Mod:{module.ModuleID}";

            if (module.DesktopModule.ModuleName == "2sxc")
            {
                var appId = new ZoneRuntime(zoneId, null).DefaultAppId;
                Log.Add($"{msg} - use def app: {appId}");
                return(wrapLog("default", appId));
            }

            if (module.ModuleSettings.ContainsKey(Settings.AppNameString))
            {
                var guid  = module.ModuleSettings[Settings.AppNameString].ToString();
                var appId = AppHelpers.GetAppIdFromGuidName(zoneId, guid);
                Log.Add($"{msg} AppG:{guid} = app:{appId}");
                return(wrapLog("ok", appId));
            }

            Log.Add($"{msg} not found = null");
            return(wrapLog("not found", null));
        }
        public string GetAutoInstallPackagesUiUrl(ISite site, IModule module, bool isContentApp)
        {
            var moduleInfo = (module as DnnModule)?.UnwrappedContents;
            var portal     = (site as DnnSite)?.UnwrappedContents;

            if (moduleInfo == null || portal == null)
            {
                throw new ArgumentException("missing portal/module");
            }

            // new: check if it should allow this
            // it should only be allowed, if the current situation is either
            // Content - and no views exist (even invisible ones)
            // App - and no apps exist - this is already checked on client side, so I won't include a check here
            if (isContentApp)
            {
                try
                {
                    var primaryAppId = new ZoneRuntime().Init(site.ZoneId, Log).DefaultAppId;
                    // we'll usually run into errors if nothing is installed yet, so on errors, we'll continue
                    var contentViews = Eav.Factory.Resolve <CmsRuntime>()
                                       .Init(State.Identity(null, primaryAppId), false, Log)
                                       .Views.GetAll();
                    if (contentViews.Any())
                    {
                        return(null);
                    }
                }
                catch { /* ignore */ }
            }

            // ReSharper disable StringLiteralTypo
            // Add desired destination
            // Add DNN Version, 2SexyContent Version, module type, module id, Portal ID
            var gettingStartedSrc =
                "//gettingstarted.2sxc.org/router.aspx?"
                + "destination=autoconfigure" + (isContentApp ? Eav.Constants.ContentAppName.ToLowerInvariant() : "app")
                + "&DnnVersion=" + Assembly.GetAssembly(typeof(Globals)).GetName().Version.ToString(4)
                + "&2SexyContentVersion=" + Settings.ModuleVersion
                + "&ModuleName=" + moduleInfo.DesktopModule.ModuleName
                + "&ModuleId=" + module.Id
                + "&PortalID=" + site.Id
                + "&ZoneID=" + site.ZoneId;
            // ReSharper restore StringLiteralTypo

            // Add DNN Guid
            var hostSettings = HostController.Instance.GetSettingsDictionary();

            gettingStartedSrc += hostSettings.ContainsKey("GUID") ? "&DnnGUID=" + hostSettings["GUID"] : "";
            // Add Portal Default Language & current language
            gettingStartedSrc += "&DefaultLanguage="
                                 + site.DefaultCultureCode
                                 + "&CurrentLanguage=" + portal.CultureCode;

            // Set src to iframe
            return(gettingStartedSrc);
        }
Beispiel #5
0
        /// <summary>
        /// Returns all Apps for the current zone
        /// </summary>
        /// <returns></returns>
        public List <IApp> GetApps(ITenant tenant, Func <Eav.Apps.App, IAppDataConfiguration> buildConfig /*, bool includeDefaultApp*/)
        {
            var appIds = new ZoneRuntime(ZoneRuntime.ZoneId, Log).Apps;

            return(appIds
                   .Select(a => new App(tenant, ZoneRuntime.ZoneId, a.Key, buildConfig, true, Log) as IApp)
                   .OrderBy(a => a.Name)
                   .ToList());
        }
Beispiel #6
0
        /// <summary>
        /// find the AppIdentity of an app which is referenced by a path
        /// </summary>
        /// <param name="appPath"></param>
        /// <returns></returns>
        internal IAppIdentity GetAppIdFromPath(string appPath)
        {
            var wrapLog = Log.Call(appPath);
            var zid     = _zoneMapper.GetZoneId(_tenantId);

            // get app from AppName
            var aid = new ZoneRuntime(zid, Log).FindAppId(appPath, true);

            wrapLog($"found app:{aid}");
            return(new AppIdentity(zid, aid));
        }
Beispiel #7
0
        /// <summary>
        /// Returns all Apps for the current zone
        /// </summary>
        /// <returns></returns>
        public List <IApp> GetApps(ISite site, Func <Eav.Apps.App, IAppDataConfiguration> buildConfig)
        {
            var zId    = ZoneRuntime.ZoneId;
            var appIds = new ZoneRuntime().Init(zId, Log).Apps;

            return(appIds
                   .Select(a => ServiceProvider.Build <App>()
                           .PreInit(site)
                           .Init(new AppIdentity(zId, a.Key), buildConfig, Log) as IApp)
                   .OrderBy(a => a.Name)
                   .ToList());
        }
Beispiel #8
0
        /// <summary>
        /// Returns all Apps for the current zone
        /// </summary>
        /// <returns></returns>
        public List <IApp> GetApps(ITenant tenant, Func <Eav.Apps.App, IAppDataConfiguration> buildConfig)
        {
            var zId    = ZoneRuntime.ZoneId;
            var appIds = new ZoneRuntime(zId, Log).Apps;

            return(appIds
                   .Select(a => Factory.Resolve <App>()
                           .PreInit(tenant)
                           .Init(new AppIdentity(zId, a.Key), buildConfig, true, Log) as IApp)
                   .OrderBy(a => a.Name)
                   .ToList());
        }
Beispiel #9
0
        /// <summary>
        /// Returns all Apps for the current zone
        /// </summary>
        /// <returns></returns>
        public static List <App> GetApps(int zoneId, bool includeDefaultApp, ITenant tenant, Log parentLog)
        {
            var appIds    = new ZoneRuntime(zoneId, parentLog).Apps;
            var builtApps = appIds.Select(eavApp => new App(tenant, zoneId, eavApp.Key));

            if (!includeDefaultApp)
            {
                builtApps = builtApps.Where(a => a.Name != Eav.Constants.ContentAppName);
            }

            return(builtApps.OrderBy(a => a.Name).ToList());
        }
Beispiel #10
0
        /// <summary>
        /// Returns all Apps for the current zone
        /// </summary>
        /// <returns></returns>
        public static List <App> GetApps(int zoneId, bool includeDefaultApp, PortalSettings ownerPs, Log parentLog)
        {
            var appIds   = new ZoneRuntime(zoneId, parentLog).Apps;// State.GetAppList(zoneId);
            var sexyApps = appIds.Select(eavApp => new App(zoneId, eavApp.Key, ownerPs));

            if (!includeDefaultApp)
            {
                sexyApps = sexyApps.Where(a => a.Name != Constants.ContentAppName);
            }

            return(sexyApps.OrderBy(a => a.Name).ToList());
        }
Beispiel #11
0
        /// <summary>
        /// New implementation to replace previous
        /// </summary>
        /// <returns></returns>
        internal int GetAppIdFromPath(int zoneId, string appPath, bool required)
        {
            var wrapLog = Log.Call <int>($"{zoneId}, {appPath}, {required}");
            // get app from AppName
            var aid = new ZoneRuntime().Init(zoneId, Log).FindAppId(appPath, true);

            if (aid <= Eav.Constants.AppIdEmpty && required)
            {
                throw new Exception($"App required but can't find App based on the name '{appPath}'");
            }

            return(wrapLog($"found app:{aid}", aid));
        }
        public IEnumerable <Feature> Features(int appId)
        {
            // some dialogs don't have an app-id yet, because no app has been selected
            // in this case, use the app-id of the content-app for feature-permission check
            if (appId == 0)
            {
                var environment = Factory.Resolve <IEnvironmentFactory>().Environment(Log);
                var zoneId      = environment.ZoneMapper.GetZoneId(PortalSettings.PortalId);
                appId = new ZoneRuntime(zoneId, Log).DefaultAppId;
            }

            return(FeatureListWithPermissionCheck(new MultiPermissionsApp(BlockBuilder, appId, Log)));
        }
Beispiel #13
0
        /// <inheritdoc />
        /// <summary>
        /// Returns all DNN Cultures with active / inactive state
        /// </summary>
        public List <TempTempCulture> CulturesWithState(int tenantId, int zoneId)
        {
            // note:
            var availableEavLanguages = new ZoneRuntime(zoneId, Log).Languages(true);
            var defaultLanguageCode   = new PortalSettings(tenantId).DefaultLanguage;

            return((from c in LocaleController.Instance.GetLocales(tenantId)
                    select new TempTempCulture(
                        c.Value.Code,
                        c.Value.Text,
                        availableEavLanguages.Any(a => a.Active && a.Matches(c.Value.Code)))
                    )
                   .OrderByDescending(c => c.Key == defaultLanguageCode)
                   .ThenBy(c => c.Key).ToList());
        }
Beispiel #14
0
        /// <summary>
        /// Get all the specs for this content-block from the entity
        /// </summary>
        /// <returns></returns>
        private IBlockIdentifier LoadBlockDefinition(int zoneId, IEntity blockDefinition, ILog log)
        {
            var appName = blockDefinition.Value <string>(CbPropertyApp) ?? "";

            IsContentApp = appName == Eav.Constants.DefaultAppName;
            var temp = blockDefinition.Value <string>(CbPropertyContentGroup) ?? "";

            Guid.TryParse(temp, out var contentGroupGuid);

            temp = blockDefinition.Value <string>(ViewParts.TemplateContentType) ?? "";
            Guid.TryParse(temp, out var previewTemplateGuid);

            var appId = new ZoneRuntime().Init(zoneId, log).FindAppId(appName);

            return(new BlockIdentifier(zoneId, appId, contentGroupGuid, previewTemplateGuid));
        }
Beispiel #15
0
        private int GetInstanceAppId(int zoneId)
        {
            var zoneRt = new ZoneRuntime().Init(zoneId, Log);

            if (IsPrimary)
            {
                return(zoneRt.DefaultAppId);
            }

            if (!_settings.ContainsKey(Settings.ModuleSettingApp))
            {
                return(Eav.Constants.AppIdEmpty);
            }

            var guid  = _settings[Settings.ModuleSettingApp] ?? "";
            var appId = zoneRt.FindAppId(guid);

            return(appId);
        }
Beispiel #16
0
        /// <summary>
        /// Returns all DNN Cultures with active / inactive state
        /// </summary>
        public List <TempTempCulture> CulturesWithState(int tennantId, int zoneId)
        {
            // note:
            var availableEavLanguages = new ZoneRuntime(zoneId, Log).Languages(true);
            var defaultLanguageCode   = new PortalSettings(tennantId).DefaultLanguage;
            var defaultLanguage       = availableEavLanguages
                                        .FirstOrDefault(p => p.Matches(defaultLanguageCode));

            //var defaultLanguageIsActive = defaultLanguage?.Active == true;

            return((from c in LocaleController.Instance.GetLocales(tennantId)
                    select new TempTempCulture(
                        c.Value.Code,
                        c.Value.Text,
                        availableEavLanguages.Any(a => a.Active && a.Matches(c.Value.Code))
                        //,
                        //string.Equals(c.Value.Code, defaultLanguageCode, StringComparison.InvariantCultureIgnoreCase) && !defaultLanguageIsActive ||
                        //defaultLanguageIsActive && !string.Equals(c.Value.Code, defaultLanguageCode,
                        //    StringComparison.InvariantCultureIgnoreCase)
                        )
                    )
                   .OrderByDescending(c => c.Key == defaultLanguageCode)
                   .ThenBy(c => c.Key).ToList());
        }
Beispiel #17
0
        /// <summary>
        /// Create app-describing entity for configuration and add Settings and Resources Content Type
        /// </summary>
        internal static void EnsureAppIsConfigured(int zoneId, int appId, Log parentLog, string appName = null)
        {
            var appAssignment = SystemRuntime.MetadataType(Constants.AppAssignmentName);
            var scope         = Settings.AttributeSetScopeApps;
            var mds           = DataSource.GetMetaDataSource(zoneId, appId);
            var appMetaData   = mds.GetMetadata(appAssignment, appId, Settings.AttributeSetStaticNameApps).FirstOrDefault();
            var appResources  = mds.GetMetadata(appAssignment, appId, Settings.AttributeSetStaticNameAppResources).FirstOrDefault();
            var appSettings   = mds.GetMetadata(appAssignment, appId, Settings.AttributeSetStaticNameAppSettings).FirstOrDefault();

            // Get appName from cache - stop if it's a "Default" app
            var eavAppName = new ZoneRuntime(zoneId, parentLog).GetName(appId);// State.GetAppName(zoneId, appId);

            if (eavAppName == Eav.Constants.DefaultAppName)
            {
                return;
            }

            var appMan = new AppManager(zoneId, appId);

            if (appMetaData == null)
            {
                appMan.MetadataEnsureTypeAndSingleEntity(scope,
                                                         Settings.AttributeSetStaticNameApps,
                                                         "App Metadata",
                                                         appAssignment,
                                                         new Dictionary <string, object>()
                {
                    { "DisplayName", IsNullOrEmpty(appName) ? eavAppName : appName },
                    { "Folder", IsNullOrEmpty(appName) ? eavAppName : RemoveIllegalCharsFromPath(appName) },
                    { "AllowTokenTemplates", "False" },
                    { "AllowRazorTemplates", "False" },
                    { "Version", "00.00.01" },
                    { "OriginalId", "" }
                });
            }


            // Add new (empty) ContentType for Settings
            if (appSettings == null)
            {
                appMan.MetadataEnsureTypeAndSingleEntity(scope,
                                                         Settings.AttributeSetStaticNameAppSettings,
                                                         "Stores settings for an app",
                                                         appAssignment,
                                                         null);
            }

            // add new (empty) ContentType for Resources
            if (appResources == null)
            {
                appMan.MetadataEnsureTypeAndSingleEntity(scope,
                                                         Settings.AttributeSetStaticNameAppResources,
                                                         "Stores resources like translations for an app",
                                                         appAssignment,
                                                         null);
            }

            if (appMetaData == null || appSettings == null || appResources == null)
            {
                SystemManager.Purge(zoneId, appId);
            }
        }
Beispiel #18
0
        protected void InitExportXDocument(string defaultLanguage, string moduleVersion)
        {
            EnsureThisIsInitialized();

            // Create XML document and declaration
            var doc = _exportDocument = new XmlBuilder().BuildDocument();

            #region Header

            var dimensions = new ZoneRuntime(ZoneId).Languages();
            var header     = new XElement(XmlConstants.Header,
                                          _isAppExport && _appStaticName != XmlConstants.AppContentGuid
                    ? new XElement(XmlConstants.App, new XAttribute(XmlConstants.Guid, _appStaticName))
                    : null,
                                          new XElement(XmlConstants.Language, new XAttribute(XmlConstants.LangDefault, defaultLanguage)),
                                          new XElement(XmlConstants.DimensionDefinition, dimensions.Select(d => new XElement(XmlConstants.DimensionDefElement,
                                                                                                                             new XAttribute(XmlConstants.DimId, d.DimensionId),
                                                                                                                             new XAttribute(XmlConstants.Name, d.Name),
                                                                                                                             new XAttribute(XmlConstants.CultureSysKey, d.Key ?? string.Empty),
                                                                                                                             new XAttribute(XmlConstants.CultureExtKey, d.EnvironmentKey ?? string.Empty),
                                                                                                                             new XAttribute(XmlConstants.CultureIsActiveAttrib, d.Active)
                                                                                                                             )))
                                          );

            #endregion

            #region Attribute Sets

            var attributeSets = new XElement(XmlConstants.AttributeSets);

            // Go through each AttributeSetID
            foreach (var attributeSetId in AttributeSetIDs)
            {
                var id         = int.Parse(attributeSetId);
                var set        = (ContentType)AppPackage.ContentTypes[id];
                var attributes = new XElement(XmlConstants.Attributes);

                // Add all Attributes to AttributeSet including meta informations
                foreach (var x in set.Attributes.OrderBy(a => a.SortOrder))
                {
                    var attribute = new XElement(XmlConstants.Attribute,
                                                 new XAttribute(XmlConstants.Static, x.Name),
                                                 new XAttribute(XmlConstants.Type, x.Type),
                                                 new XAttribute(XmlConstants.IsTitle, x.IsTitle),
                                                 // Add Attribute MetaData
                                                 from c in AppPackage.GetMetadata(Constants.MetadataForAttribute, x.AttributeId).ToList()
                                                 select GetEntityXElement(c.EntityId, c.Type.StaticName)
                                                 );

                    attributes.Add(attribute);
                }

                // Add AttributeSet / Content Type
                var attributeSet = new XElement(XmlConstants.AttributeSet,
                                                new XAttribute(XmlConstants.Static, set.StaticName),
                                                new XAttribute(XmlConstants.Name, set.Name),
                                                new XAttribute(XmlConstants.Description, set.Description),
                                                new XAttribute(XmlConstants.Scope, set.Scope),
                                                new XAttribute(XmlConstants.AlwaysShareConfig, set.AlwaysShareConfiguration),
                                                attributes);

                // Add Ghost-Info if content type inherits from another content type
                if (set.ParentId.HasValue)
                {
                    var parentStaticName = AppPackage.ContentTypes[set.ParentId.Value].StaticName;
                    attributeSet.Add(new XAttribute(XmlConstants.AttributeSetParentDef, parentStaticName));
                }

                attributeSets.Add(attributeSet);
            }

            #endregion

            #region Entities

            var entities = new XElement(XmlConstants.Entities);

            // Go through each Entity
            foreach (var entityId in EntityIDs)
            {
                var id = int.Parse(entityId);

                // Get the entity and ContentType from ContentContext add Add it to ContentItems
                var entity = AppPackage.Entities[id];
                entities.Add(GetEntityXElement(entity.EntityId, entity.Type.StaticName));
            }

            #endregion

            // init files (add to queue)
            AddFilesToExportQueue();

            // Create root node "SexyContent" and add ContentTypes, ContentItems and Templates
            doc.Add(new XElement(XmlConstants.RootNode,
                                 new XAttribute(XmlConstants.FileVersion, Settings.FileVersion),
                                 new XAttribute(XmlConstants.MinEnvVersion, Settings.MinimumRequiredVersion),
                                 new XAttribute(XmlConstants.MinModVersion, moduleVersion),
                                 new XAttribute(XmlConstants.ExportDate, DateTime.Now),
                                 header,
                                 attributeSets,
                                 entities,
                                 GetFilesXElements(),
                                 GetFoldersXElements()));
        }
Beispiel #19
0
        /// <summary>
        /// Get search info for each dnn module containing 2sxc data
        /// </summary>
        /// <param name="moduleInfo"></param>
        /// <param name="beginDate"></param>
        /// <returns></returns>
        public IList <SearchDocument> GetModifiedSearchDocuments(ModuleInfo moduleInfo, DateTime beginDate)
        {
            // always log with method, to ensure errors are cought
            Log.Add(() => $"start search for mod#{moduleInfo.ModuleID}");
            var searchDocuments = new List <SearchDocument>();
            var isContentModule = moduleInfo.DesktopModule.ModuleName == "2sxc";

            // New Context because PortalSettings.Current is null
            var zoneId = new Environment.DnnEnvironment(Log).ZoneMapper.GetZoneId(moduleInfo.OwnerPortalID);

            //if (!zoneId.HasValue)
            //    return searchDocuments;

            int?appId = new ZoneRuntime(zoneId, Log).DefaultAppId;

            if (!isContentModule)
            {
                appId = AppHelpers.GetAppIdFromModule(moduleInfo, zoneId);
                if (!appId.HasValue)
                {
                    return(searchDocuments);
                }
            }

            // new 2016-03-27
            var mcb  = new ModuleContentBlock(moduleInfo, Log);
            var sexy = mcb.SxcInstance;

            // old 2016-03-27
            var language = moduleInfo.CultureCode;
            //var contentGroup = sexy.App.ContentGroupManager./*AppContentGroups.*/GetContentGroupForModule(moduleInfo.ModuleID, moduleInfo.TabID);
            var res = sexy.App.ContentGroupManager.GetContentGroupForModule(moduleInfo.ModuleID, moduleInfo.TabID);
            var contentGroupGuid    = res.Item1;
            var previewTemplateGuid = res.Item2;
            var contentGroup        = sexy.App.ContentGroupManager.GetContentGroupOrGeneratePreview(contentGroupGuid, previewTemplateGuid);

            var template = contentGroup.Template;

            // This list will hold all EAV entities to be indexed
            // before 2016-02-27 2dm: var dataSource = sexy.GetViewDataSource(moduleInfo.ModuleID, false, template);
            var dataSource = sexy.Data;// ViewDataSource.ForModule(moduleInfo.ModuleID, false, template, sexy);

            if (template == null)
            {
                return(searchDocuments);
            }

            var engine = EngineFactory.CreateEngine(template);

            engine.Init(template, sexy.App, moduleInfo, 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(moduleInfo, 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.Select(p => p.Value);
                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 != null && entity.Title[language] != null ? entity.Title[language].ToString() : "(no title)",
                        ModifiedTimeUtc = (entity.Modified == DateTime.MinValue ? DateTime.Now.Date.AddHours(DateTime.Now.Hour) : entity.Modified).ToUniversalTime(),
                        UniqueKey       = "2sxc-" + moduleInfo.ModuleID + "-" + (entity.EntityGuid != new Guid() ? entity.EntityGuid.ToString() : (stream.Key + "-" + entity.EntityId)),
                        IsActive        = true,
                        TabId           = moduleInfo.TabID,
                        PortalId        = moduleInfo.PortalID
                    };

                    // Take the newest value (from ContentGroupItem and Entity)
                    if (entity is IHasEditingData)
                    {
                        var contentGroupItemModifiedUtc = ((IHasEditingData)entity).ContentGroupItemModified.ToUniversalTime();
                        searchInfo.ModifiedTimeUtc      = searchInfo.ModifiedTimeUtc > contentGroupItemModifiedUtc
                            ? searchInfo.ModifiedTimeUtc
                            : contentGroupItemModifiedUtc;
                    }

                    return(searchInfo);
                }));
            }

            // check if the cshtml has search customizations
            try
            {
                engine.CustomizeSearch(searchInfoDictionary, moduleInfo, beginDate);
            }
            catch (Exception e)
            {
                Exceptions.LogException(new SearchIndexException(moduleInfo, 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);
        }