public ActionResult CloseCase(EntityReference entityReference, string resolutionSubject, string resolutionDescription) { var portal = PortalCrmConfigurationManager.CreatePortalContext(); var context = portal.ServiceContext; var entityPermissionProvider = new CrmEntityPermissionProvider(); if (!entityPermissionProvider.PermissionsExist) { return(new HttpStatusCodeResult(HttpStatusCode.Forbidden, ResourceManager.GetString("Entity_Permissions_Have_Not_Been_Defined_Message"))); } var entity = context.RetrieveSingle(entityReference.LogicalName, FetchAttribute.None, new Condition("incidentid", ConditionOperator.Equal, entityReference.Id)); var test = entityPermissionProvider.TryAssert(context, CrmEntityPermissionRight.Write, entity); if (!test) { return(new HttpStatusCodeResult(HttpStatusCode.Forbidden, ResourceManager.GetString("DoNot_Have_Appropriate_Permissions"))); } var adapter = new CoreDataAdapter(portal, context); adapter.CloseIncident(entityReference, resolutionSubject, resolutionDescription); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Case, this.HttpContext, "close_incident", 1, entity.ToEntityReference(), "edit"); } return(new HttpStatusCodeResult(HttpStatusCode.NoContent)); }
public ActionResult CommentCreate(Guid id, string authorName, string authorEmail, string copy) { var context = PortalCrmConfigurationManager.CreateServiceContext(); var issue = context.CreateQuery("adx_issue").FirstOrDefault(adxIssue => adxIssue.GetAttributeValue <Guid>("adx_issueid") == id); if (issue == null || !Authorized(context, issue)) { return(new EmptyResult()); } var issueDataAdapter = new IssueDataAdapter(issue) { ChronologicalComments = true }; var sanitizedCopy = SafeHtml.SafeHtmSanitizer.GetSafeHtml(copy ?? string.Empty); TryAddComment(issueDataAdapter, authorName, authorEmail, sanitizedCopy); var comments = FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback) ? new PaginatedList <IComment>(PaginatedList.Page.Last, issueDataAdapter.SelectCommentCount(), issueDataAdapter.SelectComments) : null; var commentsViewModel = new IssueCommentsViewModel { Issue = issueDataAdapter.Select(), Comments = comments }; return(PartialView("Comments", commentsViewModel)); }
public ActionResult RatingCreate(Guid id, int rating, int maxRating, int minRating) { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return(new EmptyResult()); } var context = PortalCrmConfigurationManager.CreateServiceContext(); var article = context.RetrieveSingle("knowledgearticle", FetchAttribute.All, new Condition("knowledgearticleid", ConditionOperator.Equal, id), false, false, RequestFlag.AllowStaleData); if (article == null || !Authorized(context, article)) { return(new EmptyResult()); } var articleDataAdapter = new KnowledgeArticleDataAdapter(article); TryAddUpdateRating(articleDataAdapter, rating, maxRating, minRating); var commentsViewModel = new ArticleCommentsViewModel() { KnowledgeArticle = articleDataAdapter.Select() }; return(PartialView("Rating", commentsViewModel.KnowledgeArticle)); }
private ActionResult GetIssueView(Entity adxIssueForum, Entity adxIssue, int?page) { var issueDataAdapter = new IssueDataAdapter(adxIssue) { ChronologicalComments = true }; var issue = issueDataAdapter.Select(); var comments = FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback) ? new PaginatedList <IComment>(page, issueDataAdapter.SelectCommentCount(), issueDataAdapter.SelectComments) : null; var issueViewModel = new IssueViewModel { IssueForum = new IssueForumDataAdapter(adxIssueForum).Select(), Issue = issue, Comments = new IssueCommentsViewModel { Comments = comments, Issue = issue }, CurrentUserHasAlert = issueDataAdapter.HasAlert() }; return(View("Issue", issueViewModel)); }
/// <summary> /// Product initialization /// </summary> /// <param name="product">Product entity record</param> /// <param name="productMetadata">Product entity metadata</param> /// <param name="pricingInfo">Product Pricing Info</param> /// <param name="primaryImageAttachment">Primary Image Sales Attachment</param> /// <param name="thumbnailImageAttachment">Thumbnail Image Sales Attachment</param> public Product(Entity product, EntityMetadata productMetadata, IProductPricingInfo pricingInfo, ISalesAttachment primaryImageAttachment, ISalesAttachment thumbnailImageAttachment) { if (product == null) { throw new ArgumentNullException("product"); } if (productMetadata == null) { throw new ArgumentNullException("productMetadata"); } if (product.LogicalName != "product") { throw new ArgumentException(string.Format(ResourceManager.GetString("Value_Missing_For_LogicalName"), product.LogicalName), "product"); } Brand = product.GetAttributeValue <EntityReference>("adx_brand"); Currency = product.GetAttributeValue <EntityReference>("transactioncurrencyid"); DefaultPriceList = product.GetAttributeValue <EntityReference>("priceleveid"); DefaultUnit = product.GetAttributeValue <EntityReference>("defaultuomid"); Entity = product; EntityReference = product.ToEntityReference(); ImageURL = primaryImageAttachment == null ? string.Empty : primaryImageAttachment.URL; ImageThumbnailURL = thumbnailImageAttachment == null ? string.Empty : thumbnailImageAttachment.URL; PricingInfo = pricingInfo; Subject = product.GetAttributeValue <EntityReference>("subjectid"); UnitGroup = product.GetAttributeValue <EntityReference>("defaultuomscheduleid"); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Product, HttpContext.Current, "create_note", 1, product.ToEntityReference(), "create"); } }
/// <summary> /// Partially localizes the facet view constraints (localizing them all initially is too costly). /// /// Facet view JSON will be segmented into two objects, "localized" and "unlocalized", each with /// an array of constraint objects. /// </summary> /// <param name="facetView">The facet view to partially localize. Constraint values must be GUIDs.</param> /// <param name="initialConstraintsToLocalize">Number of constraints to initially localize.</param> /// <param name="localizedLabelEntityName">The name of the entity with the field to be localized.</param> /// <param name="localizedLabelField">Field on entity to be localized.</param> /// <returns></returns> private JArray GetPartialLocalizedFacetViewJson(FacetView facetView, int initialConstraintsToLocalize, string localizedLabelEntityName, string localizedLabelField) { JArray facetViewJson = new JArray(); ConstraintHit[] constraintHits = facetView.ConstraintHits.ToArray(); var hitCountsEnabled = FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching); // Convert the received GUID strings into entity references IEnumerable <EntityReference> entityReferencesToLocalize = facetView.ConstraintHits .Take(initialConstraintsToLocalize) .Select(constraintHit => new EntityReference(localizedLabelEntityName, new Guid(constraintHit.ConstraintValue))); // Get the localized labels based off the entity references and the field to localize var localizedLabels = MapEntityReferencesToLocalizedLabels(entityReferencesToLocalize, localizedLabelField); foreach (ConstraintHit constraint in constraintHits) { string localizedConstraintName; localizedLabels.TryGetValue(Guid.Parse(constraint.ConstraintValue), out localizedConstraintName); // Set localized labels, keep all not-localized labels empty facetViewJson.Add( new JObject { { "displayName", localizedConstraintName }, { "name", constraint.ConstraintValue }, { "hitCount", hitCountsEnabled ? constraint.HitCount.ToString() : string.Empty } }); } return(facetViewJson); }
/// <summary> /// Returns the number of comments that have been posted for the article this adapter applies to. /// </summary> public virtual int SelectCommentCount() { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return(0); } var serviceContext = Dependencies.GetServiceContext(); var includeUnapprovedComments = TryAssertCommentModerationPermission(serviceContext); return(serviceContext.FetchCount("feedback", "feedbackid", addCondition => { addCondition("regardingobjectid", "eq", KnowledgeArticle.Id.ToString()); addCondition("statecode", "eq", "0"); if (!includeUnapprovedComments) { addCondition("adx_approved", "eq", "true"); } }, null, addBinaryFilterCondition => { addBinaryFilterCondition("comments", "not-null"); })); }
public IEnumerable <IComment> SelectComments(int startRowIndex, int maximumRows = -1) { var comments = new List <Comment>(); if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback) || maximumRows == 0) { return(comments); } var includeUnapprovedComments = TryAssertCommentModerationPermission(Dependencies); var query = OrganizationServiceContextExtensions.SelectCommentsByPage( OrganizationServiceContextExtensions.GetPageInfo(startRowIndex, maximumRows), WebPageReference.Id, includeUnapprovedComments); var commentsEntitiesResult = Dependencies.GetServiceContext().RetrieveMultiple(query); comments.AddRange( commentsEntitiesResult.Entities.Select( commentEntity => new Comment( commentEntity, new Lazy <ApplicationPath>(() => Dependencies.GetEditPath(commentEntity.ToEntityReference()), LazyThreadSafetyMode.None), new Lazy <ApplicationPath>(() => Dependencies.GetDeletePath(commentEntity.ToEntityReference()), LazyThreadSafetyMode.None), new Lazy <bool>(() => includeUnapprovedComments, LazyThreadSafetyMode.None), (new RatingDataAdapter(commentEntity)).GetRatingInfo(), RatingsEnabled))); return(comments); }
/// <summary> /// Submit an issue to the issue forum this adapter applies to. /// </summary> /// <param name="title">The title of the issue.</param> /// <param name="copy">The copy of the issue.</param> /// <param name="track">Create an issue alert for the current user (user must be authenticated).</param> /// <param name="authorName">The name of the author for the issue (ignored if user is authenticated).</param> /// <param name="authorEmail">The email of the author for the issue (ignored if user is authenticated).</param> public virtual void CreateIssue(string title, string copy, bool track = false, string authorName = null, string authorEmail = null) { title.ThrowOnNullOrWhitespace("title"); var httpContext = Dependencies.GetHttpContext(); var author = Dependencies.GetPortalUser(); if (!httpContext.Request.IsAuthenticated || author == null) { authorName.ThrowOnNullOrWhitespace("authorName", string.Format(ResourceManager.GetString("Error_Creating_IdeaAndIssue_Comment_WithNullOrWhitespace"), "issue")); authorEmail.ThrowOnNullOrWhitespace("authorEmail", string.Format(ResourceManager.GetString("Error_Creating_IdeaAndIssue_Comment_WithNullOrWhitespace"), "issue")); } var context = Dependencies.GetServiceContext(); var issueForum = Select(); if (!issueForum.CurrentUserCanSubmitIssues) { throw new InvalidOperationException(string.Format("The current user can't create an {0} with the current {0} submission policy.", "Issue")); } var username = httpContext.Request.IsAuthenticated ? httpContext.User.Identity.Name : httpContext.Request.AnonymousID; var issue = new Entity("adx_issue"); issue["adx_name"] = title; issue["adx_copy"] = copy; issue["adx_issueforumid"] = IssueForum; issue["adx_date"] = DateTime.UtcNow; issue["adx_partialurl"] = GetDefaultIssuePartialUrl(title); issue["adx_createdbyusername"] = username; // issue["adx_createdbyipaddress"] = httpContext.Request.UserHostAddress; issue["adx_approved"] = issueForum.IssueSubmissionPolicy != IssueForumIssueSubmissionPolicy.Moderated; if (author != null) { issue["adx_authorid"] = author; } else { issue["adx_authorname"] = authorName; issue["adx_authoremail"] = authorEmail; } context.AddObject(issue); context.SaveChanges(); if (track) { new IssueDataAdapter(issue).CreateAlert(Dependencies.GetPortalUser()); } if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Issue, HttpContext.Current, "create_issue", 1, issue.ToEntityReference(), "create"); } }
private ActionResult GetIdeasViewOrRedirectToOnlyIdeaForum(OrganizationServiceContext context) { var websiteDataAdapter = new WebsiteDataAdapter(); var ideaForums = websiteDataAdapter.SelectIdeaForums().ToArray(); var ideaForumCount = websiteDataAdapter.SelectIdeaForumCount(); foreach (var ideaForum in ideaForums) { ideaForum.Url = context.GetUrl(ideaForum.Entity); } if (ideaForums.Count() == 1) { return(this.RedirectToAction("Ideas", new { ideaForumPartialUrl = ideaForums.First().Url })); } var ideasViewModel = new IdeasViewModel { IdeaForums = ideaForums, IdeaForumCount = ideaForumCount }; if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Idea, this.HttpContext, "read_ideas_forum", string.Empty, ideaForumCount, "adx_ideaforum", "read"); } return(View("Ideas", ideasViewModel)); }
public Blog(Entity entity, ApplicationPath applicationPath, ApplicationPath feedPath = null) { if (entity == null) { throw new ArgumentNullException("entity"); } if (entity.LogicalName != "adx_blog") { throw new ArgumentException(string.Format("Value must have logical name {0}.", entity.LogicalName), "entity"); } if (applicationPath == null) { throw new ArgumentNullException("applicationPath"); } Entity = entity; ApplicationPath = applicationPath; FeedPath = feedPath; CommentPolicy = entity.GetAttributeValue <OptionSetValue>("adx_commentpolicy") == null ? BlogCommentPolicy.Open : (BlogCommentPolicy)entity.GetAttributeValue <OptionSetValue>("adx_commentpolicy").Value; Id = entity.Id; Summary = new HtmlString(entity.GetAttributeValue <string>("adx_summary")); Title = entity.GetAttributeValue <string>("adx_name"); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Blog, HttpContext.Current, "read_blog", 1, entity.ToEntityReference(), "read"); } }
public IEnumerable <CrmEntityIndexDocument> GetDocuments() { ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Start"); var dataContext = _index.DataContext; var documentFactory = new FetchXmlIndexDocumentFactory(_index, _fetchXml, _titleAttributeLogicalName, _localeConfig); var currentPageFetchXml = _fetchXml; var knowledgeArticleFilter = new FetchXmlResultsFilter(); while (true) { var request = new OrganizationRequest("ExecuteFetch"); request.Parameters["FetchXml"] = currentPageFetchXml.ToString(); var response = dataContext.Execute(request); if (response == null) { throw new InvalidOperationException("Did not receive valid response from ExecuteFetchRequest."); } var fetchXmlResponse = response.Results["FetchXmlResult"] as string; if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CmsEnabledSearching)) { if (this._fetchXml.LogicalName == "knowledgearticle") { fetchXmlResponse = knowledgeArticleFilter.Aggregate(fetchXmlResponse, "knowledgearticleid", "record2id.productid", "adx_contentaccesslevelid.adx_contentaccesslevelid", "record2id.connectionid", "annotation.filename", "annotation.notetext", "annotation.annotationid"); } if (this._fetchXml.LogicalName == "annotation") { fetchXmlResponse = knowledgeArticleFilter.Aggregate(fetchXmlResponse, "annotationid", "product.productid"); } } var resultSet = new FetchXmlResultSet(fetchXmlResponse); ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("FetchXmlResult:LogicalName={0}, Count={1}", EntityNamePrivacy.GetEntityName(this._fetchXml.LogicalName), resultSet.Count())); foreach (var document in resultSet.Select(documentFactory.GetDocument)) { yield return(document); } if (resultSet.MoreRecords) { currentPageFetchXml = currentPageFetchXml.ForNextPage(resultSet.PagingCookie); } else { break; } } ADXTrace.Instance.TraceInfo(TraceCategory.Application, "End"); }
private void InvalidateCacheDependency(string dependency) { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.PortalAllowStaleData)) { // If Stale data setting is not enabled then do the legacy behaviour of removing the dependency from the cache. CacheEventSource.Log.CacheRemove(dependency, CacheRegionName); Cache.Remove(dependency); } else { // Get the cache items for this dependency and mark those cache items as dirty. // To do this we need to enumerate over all the cache item details and which ever cache-item has this dependency mark it dirty. // To mark the cache item dirty, set the cacheItemDetail.CacheItemStatus to CacheItemStatus.Dirty. // Rest of the logic would go in Lookup and Insert method, we will not have a cache miss but we will need to check if the item is dirty, var cacheItems = from item in Cache let key = item.Key let cacheItemDetail = Cache.GetCacheItemDetail(item.Key, CacheRegionName) select new { key, cacheItemDetail }; foreach (var cacheItem in cacheItems) { if (cacheItem.cacheItemDetail == null) { continue; } if (cacheItem.cacheItemDetail.CacheItemStatus == CacheItemStatus.Dirty || cacheItem.cacheItemDetail.CacheItemStatus == CacheItemStatus.BeingProcessed) { // If the cache item is already marked dirty/BeingProcessed, skip. continue; } if (cacheItem.cacheItemDetail.Policy.ChangeMonitors.Any(item => item.CacheKeys.Contains(dependency))) { if (!cacheItem.cacheItemDetail.IsStaleDataAllowed) { // If the stale data is not allowed for the given cache key, remove this item from the cache. ADXTrace.Instance.TraceInfo(TraceCategory.CacheInfra, string.Format("Stale data is not allowed for CacheKey = {0}", cacheItem.key)); CacheEventSource.Log.CacheRemove(cacheItem.key, CacheRegionName); Cache.Remove(cacheItem.key); } // Try setting the cache item status to dirty, if successful: // a) store the session id. This session id we will use later to block the thread from returning stale data, if it is the one which marked the cache-item dirty. else if (cacheItem.cacheItemDetail.TrySetCacheItemStatus(CacheItemStatus.Dirty)) { ADXTrace.Instance.TraceInfo(TraceCategory.CacheInfra, string.Format("Cache Item is marked dirty, CacheKey = {0}", cacheItem.key)); cacheItem.cacheItemDetail.SessionId = GetSessionId(); // Remove the secondary cache item to trigger invalidation of output cache. // We must do this otherwise we may get stuck in situation where the output cache is never invalidated, and thus the dirty cache items never get refreshed. var outputCacheSecondaryDependencyKey = ObjectCacheOutputCacheProvider.GetSecondaryDependencyKey(cacheItem.key); Cache.Remove(outputCacheSecondaryDependencyKey); } } } } }
public IDictionary <string, object> GetCommentAttributes(string content, string authorName = null, string authorEmail = null, string authorUrl = null, HttpContext context = null) { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return(new Dictionary <string, object>()); } // Use write service context to ensure we're not getting the content map cached // version of the web page from the PortalContext.ServiceContext. var serviceContext = Dependencies.GetServiceContextForWrite(); var page = serviceContext.CreateQuery("adx_webpage").FirstOrDefault(p => p.GetAttributeValue <Guid>("adx_webpageid") == WebPageReference.Id); if (page == null) { throw new Exception("adx_webpage not found."); } var postedOn = DateTime.UtcNow; var policyReader = GetCommentPolicyReader(); Dictionary <string, object> attributes; attributes = new Dictionary <string, object> { { "regardingobjectid", page.ToEntityReference() }, { "createdon", postedOn }, { "title", StringHelper.GetCommentTitleFromContent(content) }, { "adx_approved", (policyReader.IsCommentPolicyOpen || policyReader.IsCommentPolicyOpenToAuthenticatedUsers) }, { "adx_createdbycontact", authorName }, { "adx_contactemail", authorEmail }, { "comments", content }, { "source", new OptionSetValue((int)FeedbackSource.Portal) } }; var portalUser = Dependencies.GetPortalUser(); if (portalUser != null && portalUser.LogicalName == "contact") { attributes[FeedbackMetadataAttributes.UserIdAttributeName] = portalUser; } else if (context != null && context.Profile != null) { attributes[FeedbackMetadataAttributes.VisitorAttributeName] = context.Profile.UserName; } if (authorUrl != null) { authorUrl = authorUrl.Contains(Uri.SchemeDelimiter) ? authorUrl : "{0}{1}{2}".FormatWith(Uri.UriSchemeHttp, Uri.SchemeDelimiter, authorUrl); if (Uri.IsWellFormedUriString(authorUrl, UriKind.Absolute)) { attributes["adx_authorurl"] = authorUrl; } } return(attributes); }
/// <summary> /// Post a comment for the idea this adapter applies to. /// </summary> /// <param name="content">The comment copy.</param> /// <param name="authorName">The name of the author for this comment (ignored if user is authenticated).</param> /// <param name="authorEmail">The email of the author for this comment (ignored if user is authenticated).</param> public virtual void CreateComment(string content, string authorName = null, string authorEmail = null) { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return; } content.ThrowOnNullOrWhitespace("content"); var title = StringHelper.GetCommentTitleFromContent(content); title.ThrowOnNullOrWhitespace("title"); var httpContext = Dependencies.GetHttpContext(); var author = Dependencies.GetPortalUser(); if (!httpContext.Request.IsAuthenticated || author == null) { authorName.ThrowOnNullOrWhitespace("authorName", string.Format(ResourceManager.GetString("Error_Creating_IdeaAndIssue_Comment_WithNullOrWhitespace"), "idea comment")); authorEmail.ThrowOnNullOrWhitespace("authorEmail", string.Format(ResourceManager.GetString("Error_Creating_IdeaAndIssue_Comment_WithNullOrWhitespace"), "idea comment")); } var context = Dependencies.GetServiceContext(); var idea = Select(); if (!idea.CurrentUserCanComment) { throw new InvalidOperationException("An idea comment can't be created with the current idea comment policy."); } var comment = new Entity("feedback"); comment["title"] = title; comment["comments"] = content; comment["regardingobjectid"] = Idea; comment["createdon"] = DateTime.UtcNow; comment["adx_approved"] = idea.CommentPolicy != IdeaForumCommentPolicy.Moderated; comment["adx_createdbycontact"] = authorName; comment["adx_contactemail"] = authorEmail; comment["source"] = new OptionSetValue((int)FeedbackSource.Portal); if (author != null && author.LogicalName == "contact") { comment[FeedbackMetadataAttributes.UserIdAttributeName] = author; } else if (context != null) { comment[FeedbackMetadataAttributes.VisitorAttributeName] = httpContext.Profile.UserName; } context.AddObject(comment); context.SaveChanges(); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Idea, HttpContext.Current, "create_idea_comment", 1, comment.ToEntityReference(), "create"); } }
private ActionResult GetArticleView(Entity articleEntity, int?page, string code) { var articleViewModel = new ArticleViewModel(articleEntity, page, code); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.KnowledgeArticle, this.HttpContext, "read_article", 1, articleEntity.ToEntityReference(), "read"); } return(View("Article", articleViewModel)); }
protected override ICrmEntityIndexSearcher CreateIndexSearcher(ICrmEntityIndex index) { var websiteId = GetWebsiteId(); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.PortalFacetedNavigation)) { return(new PortalFacetedIndexSearcher(index, websiteId)); } return(new PortalIndexSearcher(index, websiteId)); }
/// <summary> /// Adds Content Access Level and Product Filtering to fetch /// </summary> /// <param name="annotation">Annotation</param> /// <param name="context">Context</param> /// <param name="contentAccessLevelProvider">content Access Level Provider</param> /// <param name="productAccessProvider">product Access Provider</param> private bool AssertKnowledgeArticleCalAndProductFiltering(Entity annotation, OrganizationServiceContext context, ContentAccessLevelProvider contentAccessLevelProvider, ProductAccessProvider productAccessProvider) { if (!contentAccessLevelProvider.IsEnabled() & !productAccessProvider.IsEnabled()) { // If CAL and Product Filtering is not enabled then we must not restrict access to the article. This will also eliminate an unnecessary knowledge article query. return(true); } var entityReference = annotation.GetAttributeValue <EntityReference>("objectid"); var fetch = new Fetch(); var knowledgeArticleFetch = new FetchEntity("knowledgearticle") { Filters = new List <Filter> { new Filter { Type = LogicalOperator.And, Conditions = new List <Condition> { new Condition("knowledgearticleid", ConditionOperator.Equal, entityReference.Id) } } }, Links = new List <Link>() }; fetch.Entity = knowledgeArticleFetch; // Apply Content Access Level filtering. If it is not enabled the fetch will not be modified contentAccessLevelProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, fetch); // Apply Product filtering. If it is not enabled the fetch will not be modified. productAccessProvider.TryApplyRecordLevelFiltersToFetch(CrmEntityPermissionRight.Read, fetch); var kaResponse = (RetrieveMultipleResponse)context.Execute(fetch.ToRetrieveMultipleRequest()); var isValid = kaResponse.EntityCollection.Entities.Any(); if (isValid) { if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Note, HttpContext.Current, "TryCreateHandler CAL/PF passed", 1, annotation.ToEntityReference(), "read"); } return(true); } if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Note, HttpContext.Current, "TryCreateHandler CAL/PF failed", 1, annotation.ToEntityReference(), "read"); } return(false); }
public virtual ICrmEntitySearchResultPage Search(ICrmEntityQuery query) { ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format(@"query=(PageNumber={0},PageSize={1},LogicalNames=({2}))", query.PageNumber, query.PageSize, string.Join(",", query.LogicalNames.ToArray()))); var pageNumber = query.PageNumber; if (pageNumber < 1) { ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Page number cannot be less than 1. Forcing PageNumber to 1."); pageNumber = 1; } var pageSize = query.PageSize; if (pageSize < 1) { ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Page size cannot be less than 1. Forcing PageSize to 1."); pageSize = 1; } var luceneQuery = CreateQuery(query); var resultFactory = Index.GetSearchResultFactory(luceneQuery); var results = new List <ICrmEntitySearchResult>(); // We add a +1 to the searchLimit and resultLimit so as to try and go one result beyond the requested result page, so that // approximateTotalHits will reflect whether there is at least one further valid/readable result beyond the current page. // This eliminates the edge case where a user gets a full page of results, the total hits indicates there are more results, // but there actually aren't any, leading to a blank final page of results. var userResults = GetUserSearchResults( query, ((pageSize * pageNumber) * InitialSearchLimitMultiple) + 1, 0, (pageSize * pageNumber) + 1, resultFactory, pageNumber, pageSize, results); // sprinkle these calls in for whichever events we want to trace if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CustomerJourneyTracking)) { var queryStringArray = query.QueryText.Split('(', ')'); string queryString = queryStringArray.Length > 1 ? queryStringArray[1] : query.QueryText; PortalTrackingTrace.TraceInstance.Log(Constants.Search, queryString, string.Empty); } return(userResults); }
public Comment( Entity feedback, Lazy <ApplicationPath> getEditPath = null, Lazy <ApplicationPath> getDeletePath = null, Lazy <bool> editable = null, IRatingInfo ratingInfo = null, bool ratingEnabled = false) { feedback.ThrowOnNull("entity"); feedback.AssertEntityName("feedback"); Entity = feedback; var authorReference = feedback.GetAttributeValue <EntityReference>("createdbycontact"); if (authorReference != null) { var authorNameAttribute = Localization.LocalizeFullName( feedback.GetAttributeAliasedValue <string>("author.firstname"), feedback.GetAttributeAliasedValue <string>("author.lastname")); var authorEmailAttribute = feedback.GetAttributeAliasedValue <string>("author.emailaddress1"); Author = new Author(authorReference, authorNameAttribute ?? string.Empty, authorEmailAttribute ?? string.Empty); } else { var authorName = feedback.Contains("adx_createdbycontact") ? feedback["adx_createdbycontact"].ToString() : string.Empty; if (!string.IsNullOrWhiteSpace(authorName)) { var authorUrl = feedback.Contains("adx_authorurl") ? feedback["adx_authorurl"].ToString() : string.Empty; var authorauthorEmailUrl = feedback.Contains("adx_contactemail") ? feedback["adx_contactemail"].ToString() : string.Empty; Author = new Author(authorName, authorUrl, authorauthorEmailUrl); } } Content = feedback.GetAttributeValue <string>("comments"); Date = feedback.GetAttributeValue <DateTime?>("createdon") ?? feedback.GetAttributeValue <DateTime>("createdon"); Name = feedback.GetAttributeValue <string>("title"); IsApproved = feedback.GetAttributeValue <bool?>("adx_approved").GetValueOrDefault(); _getEditPath = getEditPath; _getDeletePath = getDeletePath; _editable = editable; RatingInfo = ratingInfo; RatingEnabled = ratingEnabled; if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Feedback, HttpContext.Current, "read_feedback", 1, feedback.ToEntityReference(), "read"); } }
public Case(Entity incident, EntityMetadata incidentMetadata, string url = null, Entity responsibleContact = null) { if (incident == null) { throw new ArgumentNullException("incident"); } if (incidentMetadata == null) { throw new ArgumentNullException("incidentMetadata"); } if (incident.LogicalName != "incident") { throw new ArgumentException(string.Format(ResourceManager.GetString("Value_Missing_For_LogicalName"), incident.LogicalName), "incident"); } Entity = incident; Url = url; EntityReference = incident.ToEntityReference(); CaseTypeLabel = GetEnumLabel(incident, incidentMetadata, "casetypecode"); StateLabel = GetEnumLabel(incident, incidentMetadata, "statecode"); StatusLabel = GetEnumLabel(incident, incidentMetadata, "statuscode"); Resolution = incident.GetAttributeValue <string>("adx_resolution"); ResolutionDate = incident.GetAttributeValue <DateTime?>("adx_resolutiondate"); var statecode = incident.GetAttributeValue <OptionSetValue>("statecode"); if (statecode != null) { IsActive = statecode.Value == (int)IncidentState.Active; IsCanceled = statecode.Value == (int)IncidentState.Canceled; IsResolved = statecode.Value == (int)IncidentState.Resolved; } Customer = incident.GetAttributeValue <EntityReference>("customerid"); if (responsibleContact != null) { ResponsibleContact = responsibleContact.ToEntityReference(); ResponsibleContactEmailAddress = responsibleContact.GetAttributeValue <string>("emailaddress1"); ResponsibleContactName = responsibleContact.GetAttributeValue <string>("fullname"); } if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Case, HttpContext.Current, "read_incident", 1, incident.ToEntityReference(), "read"); } }
public IDictionary <string, object> GetCommentAttributes(string content, string authorName = null, string authorEmail = null, string authorUrl = null, HttpContext context = null) { var post = Select(); if (post == null) { throw new InvalidOperationException("Unable to load adx_blogpost {0}. Please ensure that this record exists, and is accessible by the current user.".FormatWith(BlogPostReference.Id)); } var postedOn = DateTime.UtcNow; var attributes = new Dictionary <string, object> { { "regardingobjectid", post.Entity.ToEntityReference() }, { "createdon", postedOn }, { "adx_approved", post.CommentPolicy == BlogCommentPolicy.Open || post.CommentPolicy == BlogCommentPolicy.OpenToAuthenticatedUsers }, { "title", StringHelper.GetCommentTitleFromContent(content) }, { "adx_createdbycontact", authorName }, { "adx_contactemail", authorEmail }, { "comments", content }, { "source", new OptionSetValue((int)FeedbackSource.Portal) } }; var portalUser = BlogDependencies.GetPortalUser(); if (portalUser != null && portalUser.LogicalName == "contact") { attributes[FeedbackMetadataAttributes.UserIdAttributeName] = portalUser; } else if (context != null && context.Profile != null) { attributes[FeedbackMetadataAttributes.VisitorAttributeName] = context.Profile.UserName; } if (authorUrl != null) { authorUrl = authorUrl.Contains(Uri.SchemeDelimiter) ? authorUrl : "{0}{1}{2}".FormatWith(Uri.UriSchemeHttp, Uri.SchemeDelimiter, authorUrl); if (Uri.IsWellFormedUriString(authorUrl, UriKind.Absolute)) { attributes["adx_authorurl"] = authorUrl; } } if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Blog, HttpContext.Current, "create_comment_blog", post.CommentCount, post.Entity.ToEntityReference(), "create"); } return(attributes); }
public void UpdatePost(IForumPostSubmission forumPost) { if (forumPost == null) { throw new ArgumentNullException("forumPost"); } ADXTrace.Instance.TraceInfo(TraceCategory.Application, "Start"); var entityReference = ((IForumPostInfo)forumPost).EntityReference; var serviceContext = Dependencies.GetServiceContextForWrite(); var update = new Entity("adx_communityforumpost") { Id = entityReference.Id }; if (forumPost.Name != null) { update["adx_name"] = Truncate(forumPost.Name, 100); } if (forumPost.Content != null) { update["adx_content"] = forumPost.Content; } if (update.Attributes.Any()) { serviceContext.Attach(update); serviceContext.UpdateObject(update); serviceContext.SaveChanges(); } foreach (var attachment in forumPost.Attachments) { IAnnotationDataAdapter da = new AnnotationDataAdapter(Dependencies); da.CreateAnnotation(entityReference, string.Empty, string.Empty, attachment.Name, attachment.ContentType, attachment.Content); } if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.Forum, HttpContext.Current, "edit_forum_post", 1, entityReference, "edit"); } ADXTrace.Instance.TraceInfo(TraceCategory.Application, "End"); }
/// <summary> /// Checks if particular a flag is enabled for the given request or not. /// </summary> /// <param name="value"> The value</param> /// <returns> Returns true if the flag is enabled</returns> public bool IsFlagEnabled(RequestFlag value) { switch (value) { case RequestFlag.AllowStaleData: if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.PortalAllowStaleData)) { return((this.flag & value) == value); } return(false); default: return((this.flag & value) == value); } }
protected void Session_Start(object sender, EventArgs e) { Session["init"] = 0; if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage) // ignore non-user pings && TelemetryState.IsTelemetryEnabledUserAgent() // ignore requests to and referred requests from specific paths && TelemetryState.IsTelemetryEnabledRequestPage() // only report this telemetry when the portal is configured && SetupConfig.IsPortalConfigured()) { PortalFeatureTrace.TraceInstance.LogSessionInfo(FeatureTraceCategory.SessionStart); } }
public static IDictionary <Guid, int> FetchArticleCommentCounts(this OrganizationServiceContext serviceContext, IEnumerable <Guid> articleIds) { if (!FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return(null); } return(FetchCounts(serviceContext, "feedback", "feedbackid", "knowledgearticle", "knowledgearticleid", "regardingobjectid", articleIds, addCondition => { addCondition("statecode", "eq", "0"); })); }
public static IDictionary <Guid, int> FetchIssueCommentCounts(this OrganizationServiceContext serviceContext, IEnumerable <Guid> issueIds) { if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { return(FetchCounts(serviceContext, "feedback", "feedbackid", "adx_issue", "adx_issueid", "regardingobjectid", issueIds, addCondition => { addCondition("adx_approved", "eq", "true"); addCondition("statecode", "eq", "0"); })); } else { return(new Dictionary <Guid, int>()); } }
public static IDictionary <Guid, Tuple <string, string> > FetchIssueCommentExtendedData(this OrganizationServiceContext serviceContext, IEnumerable <Guid> commentIds) { if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.Feedback)) { var ids = commentIds.ToArray(); var fetchXml = XDocument.Parse(@" <fetch mapping=""logical""> <entity name=""feedback""> <attribute name=""feedbackid"" /> <filter type=""or"" /> <link-entity name=""contact"" from=""contactid"" to=""createdbycontact"" alias=""author""> <attribute name=""fullname"" /> <attribute name=""emailaddress1"" /> </link-entity> </entity> </fetch>" ); var filter = fetchXml.Descendants("filter").First(); foreach (var id in ids) { filter.AddFetchXmlFilterCondition("feedbackid", "eq", id.ToString()); } var response = (RetrieveMultipleResponse)serviceContext.Execute(new RetrieveMultipleRequest { Query = new FetchExpression(fetchXml.ToString()) }); return(ids.ToDictionary(id => id, id => { var data = response.EntityCollection.Entities.FirstOrDefault(e => e.GetAttributeValue <Guid>("feedbackid") == id); if (data == null) { return new Tuple <string, string>(null, null); } var authorName = data.GetAttributeAliasedValue <string>("fullname", "author"); var authorEmail = data.GetAttributeAliasedValue <string>("emailaddress1", "author"); return new Tuple <string, string>(authorName, authorEmail); })); } return(new Dictionary <Guid, Tuple <string, string> >()); }
public IEnumerable <IReview> SelectReviews(int startRowIndex, int maximumRows, string sortExpression) { ADXTrace.Instance.TraceInfo(TraceCategory.Application, string.Format("startRowIndex={0}, maximumRows={1}, sortExpression={2}: Start", startRowIndex, maximumRows, sortExpression)); if (startRowIndex < 0) { throw new ArgumentException("Value must be a positive integer.", "startRowIndex"); } if (maximumRows == 0) { return(Enumerable.Empty <IReview>()); } var serviceContext = Dependencies.GetServiceContext(); var query = SelectEntities(serviceContext); var sorts = ParseSortExpression(string.IsNullOrEmpty(sortExpression) ? DefaultSortExpression : sortExpression); query = sorts.Aggregate(query, (current, sort) => sort.Item2 == SortDirection.Ascending ? current.OrderBy(sort.Item1) : current.OrderByDescending(sort.Item1)); if (startRowIndex > 0) { query = query.Skip(startRowIndex); } if (maximumRows > 0) { query = query.Take(maximumRows); } var user = Dependencies.GetPortalUser(); var website = Dependencies.GetWebsite(); var reviews = new ReviewFactory(serviceContext, user, website).Create(query); ADXTrace.Instance.TraceInfo(TraceCategory.Application, "End"); if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.TelemetryFeatureUsage)) { PortalFeatureTrace.TraceInstance.LogFeatureUsage(FeatureTraceCategory.ProductReview, HttpContext.Current, "read_product_review", string.Empty, reviews.Count(), string.Empty, "read"); } return(reviews); }
protected void CreateBlogPostDataAdapter(object sender, ObjectDataSourceEventArgs e) { e.ObjectInstance = new BlogPostDataAdapter(_portal.Value.Entity, new PortalContextDataAdapterDependencies(_portal.Value, requestContext: Request.RequestContext)); // sprinkle these calls in for whichever events we want to trace //Log Customer Journey Tracking if (FeatureCheckHelper.IsFeatureEnabled(FeatureNames.CustomerJourneyTracking)) { if (!String.IsNullOrEmpty(_portal.Value.Entity.Id.ToString()) && !String.IsNullOrEmpty(_portal.Value.Entity.GetAttributeValue <string>("adx_name"))) { PortalTrackingTrace.TraceInstance.Log(Constants.Blog, _portal.Value.Entity.Id.ToString(), _portal.Value.Entity.GetAttributeValue <string>("adx_name")); } } }