Esempio n. 1
0
            protected override bool TestShortcutTarget(OrganizationServiceContext context, Entity entity, CrmEntityRight right, CrmEntityCacheDependencyTrace dependencies)
            {
                if (entity == null)
                {
                    return(false);
                }

                return(_contentMapProvider.Using(map => TestShortcutTarget(context, entity, right, dependencies, map)));
            }
 /// <summary>
 /// Gets guids of root localized web pages for the given web page.
 /// </summary>
 /// <param name="contentMapProvider">
 /// The content map provider.
 /// </param>
 /// <param name="entityId">
 /// The webpage Id.
 /// </param>
 /// <returns>
 /// The <see cref="IEnumerable"/> of the web page GUIDs for descendant web pages.
 /// </returns>
 public static IEnumerable <Guid> GetDescendantRootWebpagesForWebpage(IContentMapProvider contentMapProvider, Guid entityId)
 {
     return(contentMapProvider.Using(contentMap => SelectAllDescendantWebpagesWithPredicates(entityId, contentMap, new List <Predicate <WebPageNode> >()
     {
         IsRootWebPage
     })));
 }
        /// <summary>
        /// Checks if the site maker has a url defined.
        /// </summary>
        /// <param name="contentMapProvider">
        /// The content map provider.
        /// </param>
        /// <param name="siteMakerName">
        /// The site maker name.
        /// </param>
        /// <returns>
        /// The <see cref="bool"/> if the site marker has a url defined.
        /// </returns>
        public static bool IsSiteMakerUrlDefined(IContentMapProvider contentMapProvider, string siteMakerName)
        {
            if (string.IsNullOrEmpty(siteMakerName))
            {
                return(false);
            }

            return(contentMapProvider.Using(
                       contentMap =>
            {
                IDictionary <EntityReference, EntityNode> lookup;
                if (!contentMap.TryGetValue("adx_sitemarker", out lookup))
                {
                    return false;
                }

                var siteMarker = lookup.Values.Cast <SiteMarkerNode>().FirstOrDefault(x => x.Name == siteMakerName);

                if (siteMarker == null)
                {
                    return false;
                }

                var webpage = siteMarker.WebPage;
                if (webpage == null)
                {
                    return false;
                }

                return IsWebPageUrlDefined(webpage);
            }));
        }
        public override bool TryCreateHandler(IPortalContext portal, out IHttpHandler handler)
        {
            IHttpHandler local  = null;
            var          result = _contentMapProvider.Using(map => TryCreateHandler(portal, map, out local));

            handler = local;

            return(result);
        }
        /// <summary>
        /// Checks if the web page url defined.
        /// </summary>
        /// <param name="contentMapProvider">
        /// The content map provider.
        /// </param>
        /// <param name="entityId">
        /// The entity id.
        /// </param>
        /// <param name="additionalPartialUrl">
        /// OPTIONAL: additional Partial Url to be added to the webpages url.
        /// </param>
        /// <returns>
        /// If the webpage has a URL defined or not.
        /// </returns>
        public static bool IsWebPageUrlDefined(IContentMapProvider contentMapProvider, Guid entityId, string additionalPartialUrl = null)
        {
            return(contentMapProvider.Using(
                       delegate(ContentMap contentMap)
            {
                EntityNode entity;
                if (!contentMap.TryGetValue(new EntityReference("adx_webpage", entityId), out entity))
                {
                    ADXTrace.Instance.TraceWarning(TraceCategory.Monitoring, string.Format("Web Page url is not defined. EntityId: {0}", entityId));
                    return false;
                }

                var webPage = entity as WebPageNode;

                return IsWebPageUrlDefined(webPage, additionalPartialUrl);
            }));
        }
        /// <summary>
        /// Gets guids of descendant localized web pages for the given web page.
        /// </summary>
        /// <param name="contentMapProvider">
        /// The content map provider.
        /// </param>
        /// <param name="entityId">
        /// The webpage Id.
        /// </param>
        /// <param name="lcid">
        /// The lcid for the page if it's a content page.
        /// </param>
        /// <returns>
        /// The <see cref="IEnumerable"/> of the web page GUIDs for descendant web pages.
        /// </returns>
        public static IEnumerable <Guid> GetDescendantLocalizedWebpagesForWebpage(IContentMapProvider contentMapProvider, Guid entityId, int?lcid = null)
        {
            var predicates = new List <Predicate <WebPageNode> >()
            {
                IsContentPage
            };

            if (lcid.HasValue)
            {
                Predicate <WebPageNode> isLocalized = new Predicate <WebPageNode>((WebPageNode webPageNode) =>
                {
                    return(webPageNode.WebPageLanguage.PortalLanguage.Lcid == lcid.Value);
                });
                predicates.Add(isLocalized);
            }

            return(contentMapProvider.Using(contentMap => SelectAllDescendantWebpagesWithPredicates(entityId, contentMap, predicates)));
        }
Esempio n. 7
0
        /// <summary>
        /// Setup Culture for localization and globalization of the application.
        /// </summary>
        /// <param name="website"></param>
        /// <param name="legacyWebsiteLcid">CrmWebsite.Language value, for backwards compatibility with legacy pre-Multi-Language CRM environments.</param>
        /// <param name="bundles"></param>
        /// <param name="registerAction"></param>
        private static void UseLocalizedBundles(Entity website, int legacyWebsiteLcid, IContentMapProvider contentMapProvider, BundleCollection bundles, Action <BundleCollection, CultureInfo> registerAction)
        {
            // For backward compatibility with pre-Multi-Language CRM environments.
            // At this point in code execution, PortalContext is not available yet, so check for existance of adx_defaultlanguage field to determine if this is legacy environment or not.
            if (!ContextLanguageInfo.IsCrmMultiLanguageEnabledInWebsite(website))
            {
                if (legacyWebsiteLcid != 0)
                {
                    CultureInfo culture = new CultureInfo(legacyWebsiteLcid);
                    CultureInfo.DefaultThreadCurrentCulture   = culture;
                    CultureInfo.DefaultThreadCurrentUICulture = culture;
                    registerAction(bundles, culture);
                }
                return;
            }

            // Note: for environments WITH multi-language, the CurrentCulture will be set by ContextLanguageInfo.BuildContextLanguageInfo(...)

            // Not able to use portal language context so getting language directly
            // (portal context depends on owin context which is accesible only per request, not on startup)

            WebsiteNode websiteNode = null;

            contentMapProvider.Using(contentMap => contentMap.TryGetValue(website, out websiteNode));

            if (websiteNode == null)
            {
                registerAction(bundles, CultureInfo.CurrentCulture);
            }

            foreach (var websiteLanguage in websiteNode.WebsiteLanguages)
            {
                var portalLanguage = websiteLanguage.PortalLanguage;
                var culture        = ContextLanguageInfo.GetCulture(portalLanguage.CrmLanguage ?? 0);

                registerAction(bundles, culture);
            }
        }
        /// <summary>
        /// Checks if the forum url is defined.
        /// </summary>
        /// <param name="contentMapProvider">
        /// The content map provider.
        /// </param>
        /// <param name="entityId">
        /// The entity id.
        /// </param>
        /// <returns>
        /// <see cref="bool"/>If the forum has a URL defined or not.
        /// </returns>
        public static bool IsForumUrlDefined(IContentMapProvider contentMapProvider, Guid entityId)
        {
            return(contentMapProvider.Using(
                       contentMap =>
            {
                EntityNode entity;
                if (!contentMap.TryGetValue(new EntityReference("adx_communityforum", entityId), out entity))
                {
                    return false;
                }

                var forum = entity as ForumNode;

                if (forum == null)
                {
                    return false;
                }

                var partialUrl = forum.PartialUrl;

                return IsWebPageUrlDefined(forum.ParentPage, partialUrl);
            }));
        }
        public override Entity GetWebsite(OrganizationServiceContext context, Entity entity)
        {
            if (HttpContext.Current != null)
            {
                var website = HttpContext.Current.GetWebsite();
                if (website != null)
                {
                    return(context.MergeClone(website.Entity));
                }
            }

            if (context == null)
            {
                throw new ArgumentNullException("context");
            }

            if (entity == null)
            {
                return(null);
            }

            return(_contentMapProvider.Using(map => GetWebsite(context, entity, map)));
        }
        private static IEnumerable <Tuple <string, string, int> > ContentStyles(IPortalViewContext portalViewContext, IEnumerable <EntityReference> path, IContentMapProvider contentMapProvider)
        {
            var urlProvider = PortalCrmConfigurationManager.CreateDependencyProvider(portalViewContext.PortalName).GetDependency <IContentMapEntityUrlProvider>();

            if (urlProvider == null)
            {
                return(Enumerable.Empty <Tuple <string, string, int> >());
            }

            ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Getting content styles using Content Map.");

            var cssWebFileNodes = contentMapProvider.Using(map => path.SelectMany((pathItem, pathOffset) =>
            {
                WebPageNode webPage;

                // Guard against null reference exception on webPage.WebFiles. This might happen if WebPage is a translated content, but for whatever reason has no root web page.
                if (!map.TryGetValue(pathItem, out webPage) || webPage.WebFiles == null)
                {
                    return(Enumerable.Empty <Tuple <int, int, string, string> >());
                }

                return(webPage.WebFiles
                       .Where(e => e.PartialUrl != null && e.PartialUrl.EndsWith(".css"))
                       .Select(e => new Tuple <int, int, string, string>(
                                   pathOffset,
                                   e.DisplayOrder.GetValueOrDefault(0),
                                   urlProvider.GetUrl(map, e),
                                   e.PartialUrl)));
            }));

            return(cssWebFileNodes
                   .Where(e => !string.IsNullOrEmpty(e.Item3))
                   .OrderByDescending(e => e.Item1)
                   .ThenBy(e => e.Item2)
                   .Select(e => new Tuple <string, string, int>(e.Item3, e.Item4, e.Item1))
                   .ToArray());
        }
        /// <summary>
        /// Process the message from the HTTP POST request and rebuild the search index.
        /// </summary>
        /// <param name="message"></param>
        public static void ProcessMessage(OrganizationServiceCachePluginMessage message, SearchIndexInvalidationData searchIndexInvalidationData = null, OrganizationServiceContext serviceContext = null)
        {
            if (!SearchManager.Enabled)
            {
                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Search isn't enabled for the current application.");

                return;
            }

            if (message == null)
            {
                ADXTrace.Instance.TraceError(TraceCategory.Application, "Search Index build failure. Plugin Message is null.");

                return;
            }

            SearchProvider provider;
            var            forceBuild = message.Target != null && message.Target.LogicalName == "adx_website";

            if (!TryGetSearchProvider(out provider))
            {
                ADXTrace.Instance.TraceError(TraceCategory.Application, "Search Index build failure. Search Provider could not be found.");

                return;
            }

            if (forceBuild || BuildMessages.Contains(message.MessageName, MessageComparer))
            {
                PerformBuild(provider);

                ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Search Index was successfully built.");

                return;
            }

            IContentMapProvider contentMapProvider = AdxstudioCrmConfigurationManager.CreateContentMapProvider();

            if (UpdateMessages.Contains(message.MessageName, MessageComparer))
            {
                if (message.Target == null || string.IsNullOrEmpty(message.Target.LogicalName))
                {
                    throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an EntityName (entity logical name) parameter.", message.MessageName));
                }

                if (message.Target == null || message.Target.Id == Guid.Empty)
                {
                    throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an ID (entity ID) parameter.", message.MessageName));
                }

                if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                {
                    if (message.Target.LogicalName == "savedquery")
                    {
                        var cachedSavedQuery = SearchMetadataCache.Instance.SearchSavedQueries.FirstOrDefault(x => x.SavedQueryId == message.Target.Id);
                        if (cachedSavedQuery != null)
                        {
                            // SavedQueryUniqueId is timestamp to verify which change was published and need to invalidate Search Index
                            var actualSavedQueryUniqueId = SearchMetadataCache.Instance.GetSavedQueryUniqueId(message.Target.Id);
                            if (cachedSavedQuery.SavedQueryIdUnique != actualSavedQueryUniqueId)
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateEntitySet(cachedSavedQuery.EntityName));
                                SearchMetadataCache.Instance.CompleteMetadataUpdateForSearchSavedQuery(cachedSavedQuery, actualSavedQueryUniqueId);
                            }
                        }
                    }

                    if (message.Target.LogicalName == "adx_webpage" && searchIndexInvalidationData != null)
                    {
                        // bypass cache and go straight to CRM in case cache hasn't been updated yet
                        var response = serviceContext.Execute(new RetrieveRequest {
                            Target    = new EntityReference(message.Target.LogicalName, message.Target.Id),
                            ColumnSet = new ColumnSet(new string[] {
                                "adx_parentpageid",
                                "adx_websiteid",
                                "adx_publishingstateid",
                                "adx_partialurl"
                            })
                        }) as RetrieveResponse;

                        if (response != null && response.Entity != null)
                        {
                            var updatedWebPage = response.Entity;

                            // If the parent page or website change, we need to invalidate that whole section of the web page hierarchy since the web roles
                            // may change, including both root and content pages if MLP is enabled.
                            if (!EntityReferenceEquals(searchIndexInvalidationData.ParentPage, updatedWebPage.GetAttributeValue <EntityReference>("adx_parentpageid")) ||
                                !EntityReferenceEquals(searchIndexInvalidationData.Website, updatedWebPage.GetAttributeValue <EntityReference>("adx_websiteid")))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_webpage", message.Target.Id));
                            }
                            // If the publishing state or partial URL change, this will effect all the content pages and localized entities underneath them
                            // if MLP is enabled. If MLP is disabled, LCID will equal null, and then just all pages/entities underneath this will reindex.
                            else if (!EntityReferenceEquals(searchIndexInvalidationData.PublishingState, updatedWebPage.GetAttributeValue <EntityReference>("adx_publishingstateid")) ||
                                     searchIndexInvalidationData.PartialUrl != updatedWebPage.GetAttributeValue <string>("adx_partialurl"))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_webpage", message.Target.Id, searchIndexInvalidationData.Lcid));
                            }
                        }
                    }

                    if (message.Target.LogicalName == "adx_webpageaccesscontrolrule_webrole")
                    {
                        contentMapProvider.Using(contentMap =>
                        {
                            WebPageAccessControlRuleToWebRoleNode webAccessControlToWebRoleNode;

                            if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webAccessControlToWebRoleNode))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_webpage", webAccessControlToWebRoleNode.WebPageAccessControlRule.WebPage.Id));
                            }
                        });
                    }

                    if (message.Target.LogicalName == "adx_webpageaccesscontrolrule")
                    {
                        contentMapProvider.Using(contentMap =>
                        {
                            WebPageAccessControlRuleNode webAccessControlNode;

                            if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webAccessControlNode))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_webpage", webAccessControlNode.WebPage.Id));
                            }
                        });
                    }

                    if (message.Target.LogicalName == "adx_communityforumaccesspermission")
                    {
                        contentMapProvider.Using(contentMap =>
                        {
                            ForumAccessPermissionNode forumAccessNode;

                            if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out forumAccessNode))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_communityforum", forumAccessNode.Forum.Id));
                            }
                        });
                    }

                    if (message.Target.LogicalName == "connection")
                    {
                        var fetch = new Fetch
                        {
                            Entity = new FetchEntity("connection")
                            {
                                Filters = new[] { new Filter {
                                                      Conditions = new List <Condition> {
                                                          new Condition("connectionid", ConditionOperator.Equal, message.Target.Id)
                                                      }
                                                  } }
                            }
                        };

                        var connectionEntity = ((RetrieveSingleResponse)serviceContext.Execute(fetch.ToRetrieveSingleRequest())).Entity;

                        var record1Id = connectionEntity.GetAttributeValue <EntityReference>("record1id");
                        var record2Id = connectionEntity.GetAttributeValue <EntityReference>("record2id");

                        // new product association to knowledge article could mean new product filtering rules
                        if (record1Id != null && record1Id.LogicalName == "knowledgearticle" &&
                            record2Id != null && record2Id.LogicalName == "product")
                        {
                            PerformUpdate(provider, updater => updater.UpdateEntity("knowledgearticle", record1Id.Id));
                        }
                    }
                    if (message.Target.LogicalName == "adx_contentaccesslevel")
                    {
                        var fetch = GetEntityFetch("adx_knowledgearticlecontentaccesslevel", "knowledgearticleid",
                                                   "adx_contentaccesslevelid", message.Target.Id.ToString());

                        var entities = FetchEntities(serviceContext, fetch);
                        var guids    = entities.Select(e => e.GetAttributeValue <Guid>("knowledgearticleid")).ToList();

                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("knowledgearticle", "knowledgearticleid", guids));
                    }
                    if (message.Target.LogicalName == "product")
                    {
                        var fetch = GetEntityFetch("connection", "record2id", "record1id", message.Target.Id.ToString());

                        var entities = FetchEntities(serviceContext, fetch);
                        var guids    = entities.Select(e => e.GetAttributeValue <EntityReference>("record2id")).Select(g => g.Id).Distinct().ToList();

                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("knowledgearticle", "knowledgearticleid", guids));
                    }
                    if (message.Target.LogicalName == "annotation")
                    {
                        var annotationFetch = new Fetch
                        {
                            Entity = new FetchEntity("annotation", new[] { "objectid" })
                            {
                                Filters = new[]
                                {
                                    new Filter
                                    {
                                        Conditions = new List <Condition>
                                        {
                                            new Condition("annotationid", ConditionOperator.Equal, message.Target.Id),
                                        }
                                    }
                                }
                            }
                        };


                        var response =
                            (RetrieveSingleResponse)serviceContext.Execute(annotationFetch.ToRetrieveSingleRequest());

                        if (response.Entity == null)
                        {
                            ADXTrace.Instance.TraceError(TraceCategory.Application, $"Retrieve of annotation entity failed for annotationId : {message.Target.Id}");
                            throw new TransientNullReferenceException($"Retrieve of annotation entity failed for annotationId : {message.Target.Id}");
                        }

                        var knowledgeArticle = response.Entity?.GetAttributeValue <EntityReference>("objectid");
                        if (knowledgeArticle == null)
                        {
                            ADXTrace.Instance.TraceError(TraceCategory.Application, $"Could not find objectId in the retrieved annotation with annotationId : {message.Target.Id}");
                            throw new TransientNullReferenceException($"Could not find objectId in the retrieved annotation with annotationId : {message.Target.Id}");
                        }

                        if (knowledgeArticle.Id != Guid.Empty && knowledgeArticle.LogicalName == "knowledgearticle")
                        {
                            //Updating Knowledge Article related to this Annotation
                            PerformUpdate(provider, updater => updater.UpdateEntity("knowledgearticle", knowledgeArticle.Id));
                        }
                    }
                    //Re-indexing annotations and related knowledge articles if NotesFilter gets changes
                    if (message.Target.LogicalName == "adx_sitesetting" && message.Target.Name == "KnowledgeManagement/NotesFilter")
                    {
                        var notes             = GetAllNotes(serviceContext);
                        var knowledgeArticles = notes.Select(n => n.GetAttributeValue <EntityReference>("objectid"))
                                                .Distinct().Select(ka => ka.Id).Distinct()
                                                .ToList();

                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("annotation", "annotationid", notes.Select(n => n.Id).Distinct().ToList()));
                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("knowledgearticle", "knowledgearticleid", knowledgeArticles));

                        return;
                    }
                    if (message.Target.LogicalName == "adx_sitesetting" && message.Target.Name == "KnowledgeManagement/DisplayNotes")
                    {
                        PerformUpdateAsync(provider, updater => updater.DeleteEntitySet("annotation"));

                        var notes             = GetAllNotes(serviceContext);
                        var knowledgeArticles = notes.Select(n => n.GetAttributeValue <EntityReference>("objectid"))
                                                .Distinct().Select(ka => ka.Id).Distinct()
                                                .ToList();

                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("annotation", "annotationid", notes.Select(n => n.Id).Distinct().ToList()));
                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("knowledgearticle", "knowledgearticleid", knowledgeArticles));
                        return;
                    }
                }

                PerformUpdate(provider, updater => updater.UpdateEntity(message.Target.LogicalName, message.Target.Id));

                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Search Index was successfully updated. ({0}, {1}:{2})", message.MessageName, EntityNamePrivacy.GetEntityName(message.Target.LogicalName), message.Target.Id));

                return;
            }

            if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
            {
                if (AssociateDisassociateMessages.Contains(message.MessageName, MessageComparer))
                {
                    if (message.Target == null || string.IsNullOrEmpty(message.Target.LogicalName))
                    {
                        throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an EntityName (entity logical name) parameter.", message.MessageName));
                    }

                    if (message.Target == null || message.Target.Id == Guid.Empty)
                    {
                        throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an ID (entity ID) parameter.", message.MessageName));
                    }

                    if (message.RelatedEntities == null)
                    {
                        throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an EntityName (entity logical name) parameter.", message.MessageName));
                    }

                    if ((message.Target.LogicalName == "adx_webpage" && HasRelatedEntityType(message, "adx_webpageaccesscontrolrule")) ||
                        (message.Target.LogicalName == "adx_communityforum" && HasRelatedEntityType(message, "adx_communityforumaccesspermission")) ||
                        (message.Target.LogicalName == "adx_ideaforum" && HasRelatedEntityType(message, "adx_webrole")))
                    {
                        PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree(message.Target.LogicalName, message.Target.Id));
                    }

                    if (message.Target.LogicalName == "adx_webpageaccesscontrolrule" &&
                        (HasRelatedEntityType(message, "adx_webrole") || HasRelatedEntityType(message, "adx_publishingstate")))
                    {
                        contentMapProvider.Using(contentMap =>
                        {
                            WebPageAccessControlRuleNode webAccessControlNode;

                            if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webAccessControlNode))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_webpage", webAccessControlNode.WebPage.Id));
                            }
                        });
                    }

                    if (message.Target.LogicalName == "adx_communityforumaccesspermission" && HasRelatedEntityType(message, "adx_webrole"))
                    {
                        contentMapProvider.Using(contentMap =>
                        {
                            ForumAccessPermissionNode forumAccessNode;

                            if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out forumAccessNode))
                            {
                                PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree("adx_communityforum", forumAccessNode.Forum.Id));
                            }
                        });
                    }

                    if (message.Target.LogicalName == "adx_contentaccesslevel" && HasRelatedEntityType(message, "knowledgearticle"))
                    {
                        foreach (var entityReference in message.RelatedEntities)
                        {
                            if (entityReference.LogicalName == "knowledgearticle")
                            {
                                PerformUpdate(provider, updater => updater.UpdateEntity(entityReference.LogicalName, entityReference.Id));
                            }
                        }
                    }

                    //Perform update for disassociate messages from WebNotification Plugin
                    if (message.Target.LogicalName == "knowledgearticle" && (HasRelatedEntityType(message, "adx_contentaccesslevel")))
                    {
                        PerformUpdate(provider, updater => updater.UpdateEntity(message.Target.LogicalName, message.Target.Id));
                    }

                    ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Search Index was successfully updated. ({0}, {1}:{2})", message.MessageName, EntityNamePrivacy.GetEntityName(message.Target.LogicalName), message.Target.Id));

                    return;
                }
            }

            if (DeleteMessages.Contains(message.MessageName, MessageComparer))
            {
                if (message.Target == null || string.IsNullOrEmpty(message.Target.LogicalName))
                {
                    throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an EntityName (entity logical name) parameter.", message.MessageName));
                }

                if (message.Target == null || message.Target.Id == Guid.Empty)
                {
                    throw new HttpException((int)HttpStatusCode.BadRequest, string.Format("Message {0} requires an ID (entity ID) parameter.", message.MessageName));
                }

                if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching))
                {
                    if (message.Target.LogicalName == "adx_webpageaccesscontrolrule" && searchIndexInvalidationData.WebPage != null)
                    {
                        PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree(searchIndexInvalidationData.WebPage.LogicalName, searchIndexInvalidationData.WebPage.Id));
                    }

                    if (message.Target.LogicalName == "adx_webpageaccesscontrolrule_webrole" && searchIndexInvalidationData.WebPage != null)
                    {
                        PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree(searchIndexInvalidationData.WebPage.LogicalName, searchIndexInvalidationData.WebPage.Id));
                    }

                    if (message.Target.LogicalName == "adx_communityforumaccesspermission" && searchIndexInvalidationData.Forum != null)
                    {
                        PerformUpdateAsync(provider, updater => updater.UpdateCmsEntityTree(searchIndexInvalidationData.Forum.LogicalName, searchIndexInvalidationData.Forum.Id));
                    }

                    if (message.Target.LogicalName == "connection")
                    {
                        // To update Knowledge Article that was related to this connection(Product) we need to retrieve KAid from index
                        var relatedEntityList = GetRelatedEntities("connectionid", message.Target.Id, 1);

                        if (!relatedEntityList.Any())
                        {
                            return;
                        }

                        // Taking first here since there can only be one Knowledge Article related to connection
                        var entity = relatedEntityList.First();
                        if (entity.LogicalName != null && entity.LogicalName.Equals("knowledgearticle"))
                        {
                            PerformUpdate(provider, updater => updater.UpdateEntity("knowledgearticle", entity.Id));
                        }
                        return;
                    }
                    if (message.Target.LogicalName == "product" || message.Target.LogicalName == "adx_contentaccesslevel")
                    {
                        IEnumerable <EntityReference> relatedKnowledgeArticles = new List <EntityReference>();
                        var indexedFieldName = "adx_contentaccesslevel";

                        if (message.Target.LogicalName == "product")
                        {
                            indexedFieldName = FixedFacetsConfiguration.ProductFieldFacetName;
                        }

                        relatedKnowledgeArticles = GetRelatedEntities(indexedFieldName, message.Target.Id, 10000);
                        if (!relatedKnowledgeArticles.Any())
                        {
                            return;
                        }

                        var knowledgeArticlesIds =
                            relatedKnowledgeArticles.Where(r => r.LogicalName.Equals("knowledgearticle")).Select(i => i.Id).ToList();

                        PerformUpdateAsync(provider, updater => updater.UpdateEntitySet("knowledgearticle", "knowledgearticleid", knowledgeArticlesIds));
                    }
                    if (message.Target.LogicalName == "annotation")
                    {
                        var relatedKnowledgeArticles = GetRelatedEntities("annotationid", message.Target.Id, 10);
                        var knowledgeArticleId       = relatedKnowledgeArticles.Where(a => a.LogicalName == "knowledgearticle").Select(ka => ka.Id).FirstOrDefault();

                        //Updating Knowledge Article related to this Annotation
                        PerformUpdate(provider, updater => updater.UpdateEntity("knowledgearticle", knowledgeArticleId));
                    }
                }

                PerformUpdate(provider, updater => updater.DeleteEntity(message.Target.LogicalName, message.Target.Id));

                ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("Search Index was successfully updated. ({0}, {1}:{2})", message.MessageName, EntityNamePrivacy.GetEntityName(message.Target.LogicalName), message.Target.Id));

                return;
            }

            var supportedMessages = DeleteMessages.Union(BuildMessages.Union(UpdateMessages, MessageComparer), MessageComparer);

            ADXTrace.Instance.TraceError(TraceCategory.Application, string.Format(@"Search Index Build Failed. Message ""{0}"" is not supported. Valid messages are {1}.", message.MessageName, string.Join(", ", supportedMessages.ToArray())));
        }
 public override ApplicationPath GetApplicationPath(OrganizationServiceContext context, Entity entity)
 {
     return(_contentMapProvider.Using(map => GetApplicationPath(context, entity, map)));
 }
Esempio n. 13
0
        private SearchIndexBuildRequest.SearchIndexInvalidationData GetSearchIndexInvalidationData(OrganizationServiceCachePluginMessage message)
        {
            if (message.Target == null || string.IsNullOrEmpty(message.Target.LogicalName) || message.Target.Id == Guid.Empty)
            {
                return(null);
            }

            var searchIndexInvalidationData = new SearchIndexBuildRequest.SearchIndexInvalidationData();

            IContentMapProvider contentMapProvider = AdxstudioCrmConfigurationManager.CreateContentMapProvider();

            contentMapProvider.Using(contentMap =>
            {
                if (message.Target.LogicalName == "adx_webpage")
                {
                    WebPageNode webPageNode;

                    if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webPageNode))
                    {
                        searchIndexInvalidationData.PartialUrl = webPageNode.PartialUrl;

                        if (webPageNode.Parent != null)
                        {
                            searchIndexInvalidationData.ParentPage = new EntityReference("adx_webpage", webPageNode.Parent.Id);
                        }

                        if (webPageNode.Website != null)
                        {
                            searchIndexInvalidationData.Website = new EntityReference("adx_website", webPageNode.Website.Id);
                        }

                        if (webPageNode.PublishingState != null)
                        {
                            searchIndexInvalidationData.PublishingState = new EntityReference("adx_publishingstate", webPageNode.PublishingState.Id);
                        }
                    }
                }

                if (message.Target.LogicalName == "adx_webpageaccesscontrolrule_webrole")
                {
                    WebPageAccessControlRuleToWebRoleNode webAccessControlToWebRoleNode;

                    if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webAccessControlToWebRoleNode))
                    {
                        WebPageAccessControlRuleNode webAccessControlNode = webAccessControlToWebRoleNode.WebPageAccessControlRule;
                        if (webAccessControlNode != null && webAccessControlNode.WebPage != null)
                        {
                            searchIndexInvalidationData.WebPage = new EntityReference("adx_webpage", webAccessControlNode.WebPage.Id);
                        }
                    }
                }

                if (message.Target.LogicalName == "adx_webpageaccesscontrolrule")
                {
                    WebPageAccessControlRuleNode webAccessControlNode;

                    if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out webAccessControlNode))
                    {
                        if (webAccessControlNode.WebPage != null)
                        {
                            searchIndexInvalidationData.WebPage = new EntityReference("adx_webpage", webAccessControlNode.WebPage.Id);
                        }
                    }
                }

                if (message.Target.LogicalName == "adx_communityforumaccesspermission")
                {
                    ForumAccessPermissionNode forumAccessNode;

                    if (contentMap.TryGetValue(new EntityReference(message.Target.LogicalName, message.Target.Id), out forumAccessNode))
                    {
                        if (forumAccessNode.Forum != null)
                        {
                            searchIndexInvalidationData.Forum = new EntityReference("adx_communityforum", forumAccessNode.Forum.Id);
                        }
                    }
                }
            });

            return(searchIndexInvalidationData);
        }
 /// <summary>
 /// Gets the given forums web roles.
 /// </summary>
 /// <param name="contentMapProvider">
 /// The content map provider.
 /// </param>
 /// <param name="forumid">
 /// The forumid.
 /// </param>
 /// <returns>
 /// The <see cref="IEnumerable"/> of web roles associated to the forums.
 /// </returns>
 public static IEnumerable <string> GetForumsWebRoles(IContentMapProvider contentMapProvider, Guid forumid)
 {
     return(contentMapProvider.Using(contentMap => SelectAllForumsWebRoles(forumid, contentMap)));
 }
 /// <summary>
 /// Gets the given web pages web roles.
 /// </summary>
 /// <param name="contentMapProvider">
 /// The content map provider.
 /// </param>
 /// <param name="entityId">
 /// The webpage Id.
 /// </param>
 /// <returns>
 /// The <see cref="IEnumerable"/> of the associated webroles name for the given Webpage.
 /// </returns>
 public static IEnumerable <string> GetWebPageWebRoles(IContentMapProvider contentMapProvider, Guid entityId)
 {
     return(contentMapProvider.Using(contentMap => SelectAllWebRolesForWebpage(entityId, contentMap)));
 }
 /// <summary>
 /// Gets idea forum web roles.
 /// </summary>
 /// <param name="contentMapProvider">
 /// The content map provider.
 /// </param>
 /// <param name="ideaForumId">
 /// The idea forum id.
 /// </param>
 /// <returns>
 /// The <see cref="IEnumerable"/> of web roles associated to the Idea Forum.
 /// </returns>
 public static IEnumerable <string> GetIdeaForumWebRoles(IContentMapProvider contentMapProvider, Guid ideaForumId)
 {
     return(contentMapProvider.Using(contentMap => SelectAllIdeaForumWebRoles(ideaForumId, contentMap)));
 }