Exemplo n.º 1
0
        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));
        }
Exemplo n.º 2
0
        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));
        }
Exemplo n.º 5
0
        /// <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");
            }));
        }
Exemplo n.º 8
0
        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");
            }
        }
Exemplo n.º 10
0
        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));
        }
Exemplo n.º 11
0
        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");
        }
Exemplo n.º 13
0
        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);
                        }
                    }
                }
            }
        }
Exemplo n.º 14
0
        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));
        }
Exemplo n.º 18
0
        /// <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);
        }
Exemplo n.º 19
0
        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");
            }
        }
Exemplo n.º 21
0
        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");
            }
        }
Exemplo n.º 22
0
        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");
            }));
        }
Exemplo n.º 27
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>());
     }
 }
Exemplo n.º 28
0
        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> >());
        }
Exemplo n.º 29
0
        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);
        }
Exemplo n.º 30
0
        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"));
                }
            }
        }