Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <remarks>If we are changing the accepted answer, for now we are ok with multiple authors getting credit for an accepted answer BUT we only want to allow a single user to be rewarded 1x per answer. </remarks>
        protected void AcceptAnswer(object sender, AcceptAnswerEventArgs <int, int, int> e)
        {
            var objPost = Controller.GetPost(e.PostId, ModuleContext.PortalId);

            if (objPost != null)
            {
                Controller.AcceptAnswer(e.PostId, e.UserId, DateTime.Now, ModuleContext.ModuleId);

                var colUserScoring = QaSettings.GetUserScoringCollection(Controller.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);
                if (View.Model.Question.AnswerId > 0)
                {
                    // these prevent anyone for getting points 2x for the same answer (although multiple answer authors could be credited over the liftime of a question since an accepted answer can change).
                    Controller.DeleteUserScoreLog(objPost.CreatedUserId, ModuleContext.PortalId,
                                                  (int)Constants.UserScoringActions.ProvidedAcceptedAnswer, UserScoringCollection.Single(s => s.Key == Constants.UserScoringActions.ProvidedAcceptedAnswer.ToString()).Value,
                                                  e.PostId);
                    Controller.DeleteUserScoreLog(ModuleContext.PortalSettings.UserId, ModuleContext.PortalId,
                                                  (int)Constants.UserScoringActions.AcceptedQuestionAnswer, UserScoringCollection.Single(s => s.Key == Constants.UserScoringActions.AcceptedQuestionAnswer.ToString()).Value,
                                                  e.PostId);
                }

                var objAScoreLog = new UserScoreLogInfo
                {
                    UserId              = objPost.CreatedUserId,
                    PortalId            = ModuleContext.PortalId,
                    UserScoringActionId = (int)Constants.UserScoringActions.ProvidedAcceptedAnswer,
                    KeyId = e.PostId,
                    Score =
                        colUserScoring.Single(
                            s => s.Key == Constants.UserScoringActions.ProvidedAcceptedAnswer.ToString()).Value,
                    CreatedOnDate = DateTime.Now
                };

                Controller.AddScoringLog(objAScoreLog, PrivilegeCollection);

                var objScoreLog = new UserScoreLogInfo
                {
                    UserId              = ModuleContext.PortalSettings.UserId,
                    PortalId            = ModuleContext.PortalId,
                    UserScoringActionId = (int)Constants.UserScoringActions.AcceptedQuestionAnswer,
                    KeyId = e.PostId,
                    Score =
                        colUserScoring.Single(
                            s => s.Key == Constants.UserScoringActions.AcceptedQuestionAnswer.ToString()).Value,
                    CreatedOnDate = DateTime.Now
                };

                Controller.AddScoringLog(objScoreLog, PrivilegeCollection);
            }

            //TODO: CP - Journal Integration once accepted answer is in build.'
            Response.Redirect(Links.ViewQuestion(QuestionID, View.Model.Question.Title, ModuleContext.PortalSettings.ActiveTab, ModuleContext.PortalSettings), true);
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        protected void ViewLoad(object sender, EventArgs eventArgs)
        {
            try
            {
                View.Model.UserPrivileges = QaSettings.GetPrivilegeCollection(Controller.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId).ToList();
                View.OnPrivilegeSave     += OnPrivilegeSave;

                View.Refresh();
            }
            catch (Exception exc)
            {
                ProcessModuleLoadException(exc);
            }
        }
Пример #3
0
        /// <summary>
        ///
        /// </summary>
        private void BuildQaPortalSettings()
        {
            var cntQa           = new DnnqaController();
            var colOpThresholds = QaSettings.GetOpThresholdCollection(cntQa.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);

            dntbQCCVC.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.QuestionCloseCompleteVoteCount.ToString()).Value.ToString();
            dntbQCWD.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.QuestionCloseWindowDays.ToString()).Value.ToString();
            dntbQFHRC.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.QuestionFlagHomeRemoveCount.ToString()).Value.ToString();
            dntbPCVWM.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.PostChangeVoteWindowMinutes.ToString()).Value.ToString();
            dntbPFCC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.PostFlagCompleteCount.ToString()).Value.ToString();
            dntbPFWH.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.PostFlagWindowHours.ToString()).Value.ToString();
            dntbTCWD.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TagCloseWindowDays.ToString()).Value.ToString();
            dntbTFWH.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TagFlagWindowHours.ToString()).Value.ToString();
            dntbTFCC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TagFlagCompleteCount.ToString()).Value.ToString();
            dntbTSAC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TermSynonymApproveCount.ToString()).Value.ToString();
            dntbTSRC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TermSynonymRejectCount.ToString()).Value.ToString();
            dntbTSMC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TermSynonymMaxCount.ToString()).Value.ToString();
            dntbUCVC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserCloseVoteCount.ToString()).Value.ToString();
            dntbUFPMC.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserFlagPostModerateCount.ToString()).Value.ToString();
            dntbFPSC.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserFlagPostSpamCount.ToString()).Value.ToString();
            dntbUTSCMAC.Text  = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserTermSynonymCreateMinAnswerCount.ToString()).Value.ToString();
            dntbUTSVMASC.Text = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserTermSynonymVoteMinAnswerScoreCount.ToString()).Value.ToString();
            dntbUUVAC.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserUpVoteAnswerCount.ToString()).Value.ToString();
            dntbUUVQC.Text    = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.UserUpVoteQuestionCount.ToString()).Value.ToString();
            dntbQHMS.Text     = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.QuestionHomeMinScore.ToString()).Value.ToString();

            var colEmail     = QaSettings.GetEmailCollection(cntQa.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);
            var currentEmail = colEmail.Single(s => s.Key == Constants.EmailSettings.FromAddress.ToString()).Value;

            txtbxFromEmail.Text = currentEmail != @"*****@*****.**" ? currentEmail : ModuleContext.PortalSettings.Email;

            var commentTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.CommentTemplate.ToString()).Value;

            txtbxCommentEmailTemplate.Text = commentTemplate;

            var singleQuestion = colEmail.Single(s => s.Key == Constants.EmailSettings.SingleQuestionTemplate.ToString()).Value;

            txtbxQuestionEmailTemplate.Text = singleQuestion;

            var answerTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.AnswerTemplate.ToString()).Value;

            txtAnswerEmailTemplate.Text = answerTemplate;

            var summaryTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.SummaryTemplate.ToString()).Value;

            txtbxSummaryEmailTemplate.Text = summaryTemplate;
        }
Пример #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Save(object sender, EditTermEventArgs <TermHistoryInfo> e)
        {
            try
            {
                var notes = e.TermHistory.Notes;

                //TODO: allow tag name editing
                // we have our UI values temporarily stored in variables above, we can update the history item (it needs to be added PRIOR to taxonomy term update done via core API)
                // TODO: Change auto approval to off
                Controller.AddTermHistory(ModuleContext.PortalId, View.Model.SelectedTerm.TermId, notes, true, ModuleContext.ModuleId);

                var cntTerm = new DotNetNuke.Entities.Content.Taxonomy.TermController();
                var objTerm = View.Model.SelectedTerm;

                // make sure title/body are passing through security filters
                var objSecurity = new PortalSecurity();
                var description = objSecurity.InputFilter(e.TermHistory.Description, PortalSecurity.FilterFlag.NoScripting);

                objTerm.Description = description;
                cntTerm.UpdateTerm(objTerm);

                var colUserScoring = QaSettings.GetUserScoringCollection(Controller.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);
                var objScoreLog    = new UserScoreLogInfo
                {
                    UserId              = ModuleContext.PortalSettings.UserId,
                    PortalId            = ModuleContext.PortalId,
                    UserScoringActionId = (int)Constants.UserScoringActions.EditedTag,
                    Score =
                        colUserScoring.Single(
                            s => s.Key == Constants.UserScoringActions.EditedTag.ToString()).Value,
                    CreatedOnDate = DateTime.Now
                };

                Controller.AddScoringLog(objScoreLog, PrivilegeCollection);

                Response.Redirect(Links.ViewTagDetail(ModuleContext, ModuleContext.TabId, View.Model.SelectedTerm.Name), false);
            }
            catch (Exception exception)
            {
                ProcessModuleLoadException(exception);
            }
        }
Пример #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected void Save(object sender, AskQuestionEventArgs <PostInfo, bool, string> e)
        {
            try
            {
                var control = (System.Web.UI.UserControl)sender;

                if (e.Tags.Trim() == "")
                {
                    var minMsg = Localization.GetString("SelectMinTag", LocalResourceFile);
                    //var minCount = 1;
                    //minMsg = minMsg.Replace("{0}", minCount.ToString());

                    UI.Skins.Skin.AddModuleMessage(control, minMsg, ModuleMessage.ModuleMessageType.RedError);
                    return;
                }

                if (ModuleContext.Settings.ContainsKey(Constants.SettingMaxQuestionTags))
                {
                    var enteredTerms = e.Tags.Trim().Split(',').ToList();

                    if (enteredTerms.Count > Convert.ToInt32(ModuleContext.Settings[Constants.SettingMaxQuestionTags]))
                    {
                        var maxMsg = Localization.GetString("SelectMoreTags", LocalResourceFile);
                        maxMsg = maxMsg.Replace("{0}", (ModuleContext.Settings[Constants.SettingMaxQuestionTags]).ToString());

                        UI.Skins.Skin.AddModuleMessage(control, maxMsg, ModuleMessage.ModuleMessageType.RedError);
                        return;
                    }
                }

                // TODO: validate selected tags are not in the disallow collection (module setting, loop through current collection and look for disallowed tags if found show message below)
                //UI.Skins.Skin.AddModuleMessage(this, Localization.GetString("InvalidTag", SharedResourceFile), ModuleMessage.ModuleMessageType.RedError);

                if (ModuleContext.Settings.ContainsKey(Constants.SettingMinBodyChars))
                {
                    if (e.Post.Content.Length > Convert.ToInt32(ModuleContext.Settings[Constants.SettingMaxQuestionTags]))
                    {
                        UI.Skins.Skin.AddModuleMessage(control, Localization.GetString("InvalidBody", LocalResourceFile),
                                                       ModuleMessage.ModuleMessageType.RedError);
                        return;
                    }
                }

                var userEnteredTerms = e.Tags.Split(',')
                                       .Where(s => s != string.Empty)
                                       .Select(p => p.Trim())
                                       .Distinct().ToList();

                foreach (var s in userEnteredTerms)
                {
                    if (!Utils.ContainsSpecialCharacter(s))
                    {
                        continue;
                    }
                    var msg = Localization.GetString("UnAllowedCharacters", LocalResourceFile);
                    msg = msg.Replace("{0}", Constants.DisallowedCharacters);
                    UI.Skins.Skin.AddModuleMessage(control, msg, ModuleMessage.ModuleMessageType.RedError);
                    return;
                }

                var terms = new List <Term>();
                userEnteredTerms.ForEach(t => terms.Add(Terms.CreateAndReturnTerm(t, VocabularyId)));

                var colOpThresholds = QaSettings.GetOpThresholdCollection(Controller.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);
                var objTermApprove  = colOpThresholds.Single(s => s.Key == Constants.OpThresholds.TermSynonymApproveCount.ToString());
                var portalSynonyms  = Controller.GetTermSynonyms(ModuleContext.PortalId);
                var postTerms       = new List <Term>();

                foreach (var term in terms)
                {
                    var matchedSynonym = (from t in portalSynonyms where t.RelatedTermId == term.TermId && t.Score >= objTermApprove.Value select t).SingleOrDefault();
                    if (matchedSynonym != null)
                    {
                        var masterTerm = Terms.GetTermById(matchedSynonym.MasterTermId, VocabularyId);
                        // we have to make sure the masterTerm is not already in the list of terms
                        if (!terms.Contains(masterTerm))
                        {
                            postTerms.Add(masterTerm);
                            // update replaced count (for synonym)
                            Controller.TermSynonymReplaced(matchedSynonym.RelatedTermId, ModuleContext.PortalId);
                        }
                        //else
                        //{
                        //    // show it was removed?
                        //}
                    }
                    else
                    {
                        postTerms.Add(term);
                    }
                }

                e.Post.Terms.AddRange(postTerms);

                e.Post.PortalId = ModuleContext.PortalId;
                e.Post.ModuleID = ModuleContext.ModuleId;
                e.Post.Body     = Utils.ProcessSavePostBody(e.Post.Body);

                // remove line below if you want to enable post approval (changes in ascx too)
                e.Post.Approved = true;

                if (e.Post.Approved)
                {
                    e.Post.ApprovedDate = DateTime.Now;
                }

                e.Post.ParentId           = 0;
                e.Post.TabID              = ModuleContext.TabId;
                e.Post.CreatedUserId      = ModuleContext.PortalSettings.UserId;
                e.Post.CreatedDate        = DateTime.Now;
                e.Post.LastModifiedUserId = ModuleContext.PortalSettings.UserId;
                e.Post.LastModifiedDate   = DateTime.Now;

                // make sure title/body are passing through security filters
                var objSecurity = new PortalSecurity();
                e.Post.Title = objSecurity.InputFilter(e.Post.Title, PortalSecurity.FilterFlag.NoScripting | PortalSecurity.FilterFlag.NoAngleBrackets | PortalSecurity.FilterFlag.NoMarkup);
                e.Post.Body  = objSecurity.InputFilter(e.Post.Body, PortalSecurity.FilterFlag.NoScripting);

                var objPost = Controller.AddPost(e.Post, ModuleContext.TabId);
                Controller.UpdatePost(objPost, ModuleContext.TabId);

                // subscribe user
                if (e.Notify)
                {
                    var objSub = new SubscriptionInfo
                    {
                        CreatedOnDate    = DateTime.Now,
                        PortalId         = ModuleContext.PortalId,
                        PostId           = objPost.PostId,
                        SubscriptionType = (int)Constants.SubscriptionType.InstantPost,
                        UserId           = ModuleContext.PortalSettings.UserId
                    };

                    Controller.AddSubscription(objSub);
                }

                var colUserScoring = QaSettings.GetUserScoringCollection(Controller.GetQaPortalSettings(ModuleContext.PortalId), ModuleContext.PortalId);
                var objScoreLog    = new UserScoreLogInfo
                {
                    UserId              = ModuleContext.PortalSettings.UserId,
                    PortalId            = ModuleContext.PortalId,
                    UserScoringActionId = (int)Constants.UserScoringActions.AskedQuestion,
                    Score =
                        colUserScoring.Single(
                            s => s.Key == Constants.UserScoringActions.AskedQuestion.ToString()).Value,
                    CreatedOnDate = DateTime.Now
                };

                Controller.AddScoringLog(objScoreLog, PrivilegeCollection);

                // if we ever allow moderation/approval to be enabled, this needs to respect that.
                var cntJournal  = new Journal();
                var questionUrl = Links.ViewQuestion(objPost.PostId, objPost.Title, ModuleContext.PortalSettings.ActiveTab, ModuleContext.PortalSettings);

                cntJournal.AddQuestionToJournal(objPost, objPost.Title, ModuleContext.PortalId, ModuleContext.PortalSettings.UserId, questionUrl);
                Response.Redirect(questionUrl, false);
            }
            catch (Exception exception)
            {
                ProcessModuleLoadException(exception);
            }
        }
Пример #6
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private string GenerateNotifications(DateTime lastRunDate, DateTime currentRunDate, Constants.SubscriptionType subType)
        {
            var strErrors = "";

            // based on subscription type, generate list of content additions to email
            switch (subType)
            {
            case Constants.SubscriptionType.DailyTerm:
                // daily term (all questions created between dates)

                // This email is going to be user specific, so we need to start w/ a list of subscribers (based on type daily term); each user can have multiple terms
                // -- select all questions where

                // we retrieve a collection of questions, each question will have a contentItem associated with it (we only retrieve stuff not voted out)

                // we need to retrieve a collection of terms, based on content item collection from above
                strErrors = "Daily Term: Sent " + 0 + " emails <br />";
                break;

            case Constants.SubscriptionType.InstantTerm:
                var typeController  = new ContentTypeController();
                var colContentTypes = (from t in typeController.GetContentTypes() where t.ContentType == Constants.ContentTypeName select t);

                if (colContentTypes.Count() > 0)
                {
                    var contentType     = colContentTypes.Single();
                    var colContentItems = Controller.GetContentItemsByTypeAndCreated(contentType.ContentTypeId, lastRunDate, currentRunDate);

                    foreach (var item in colContentItems)
                    {
                        // we are using the question object because content item doesn't have a title association yet (for core integration)
                        var objQuestion = Controller.GetQuestionByContentItem(item.ContentItemId);

                        if (objQuestion != null)
                        {
                            // use the content item to build the email subject/body/content (sub question for content item now)
                            var colEmail    = QaSettings.GetEmailCollection(Controller.GetQaPortalSettings(objQuestion.PortalId), objQuestion.PortalId);
                            var senderEmail = colEmail.Single(s => s.Key == Constants.EmailSettings.FromAddress.ToString()).Value;
                            //var urlBase = colEmail.Single(s => s.Key == Constants.EmailSettings.PrimaryUrl.ToString()).Value;
                            var questionTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.SingleQuestionTemplate.ToString()).Value;
                            var ps = new PortalSettings(objQuestion.PortalId);

                            var titleLink     = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/question/id/" + objQuestion.PostId + "/" + DotNetNuke.Common.Globals.glbDefaultPage;
                            var subscribeLink = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/subscriptions/" + DotNetNuke.Common.Globals.glbDefaultPage;

                            var terms = "";
                            var i     = 0;
                            foreach (var t in objQuestion.Terms)
                            {
                                terms += t.Name;
                                i     += 1;

                                if (objQuestion.Terms.Count != i)
                                {
                                    terms += ", ";
                                }
                            }

                            questionTemplate = questionTemplate.Replace("[AUTHOR]", objQuestion.CreatedByDisplayName);
                            questionTemplate = questionTemplate.Replace("[TERMS]", terms);
                            questionTemplate = questionTemplate.Replace("[TITLELINK]", titleLink);
                            questionTemplate = questionTemplate.Replace("[TITLE]", objQuestion.Title);
                            questionTemplate = questionTemplate.Replace("[BODY]", Utils.ProcessDisplayPostBody(objQuestion.Body));
                            questionTemplate = questionTemplate.Replace("[SUBSCRIBELINK]", subscribeLink);

                            var colSubscribers = Controller.GetSubscribersByContentItem(item.ContentItemId, (int)Constants.SubscriptionType.InstantTerm, objQuestion.PortalId);
                            foreach (var subscriber in colSubscribers)
                            {
                                // send off the email one by one (same email to multiple subscribers)
                                Mail.SendMail(senderEmail, subscriber.Email, "", "", MailPriority.Normal,
                                              HtmlUtils.StripWhiteSpace(objQuestion.Title, true), MailFormat.Html, Encoding.UTF8, questionTemplate,
                                              "", Host.SMTPServer, Host.SMTPAuthentication, Host.SMTPUsername,
                                              Host.SMTPPassword, Host.EnableSMTPSSL);
                            }

                            strErrors = "Instant Term: Sent " + colSubscribers.Count + " emails - " + objQuestion.Title + "<br />";
                        }
                    }
                }
                else
                {
                    strErrors = "Instant Term: No email to send <br />";
                }

                break;

            default:
                var colAnswers = Controller.GetAnswersByDate(lastRunDate, currentRunDate);

                if (colAnswers.Count() > 0)
                {
                    // for each content item in the collection, get a list of subscribers and send the emails off one by one.
                    foreach (var item in colAnswers)
                    {
                        var objQuestion = Controller.GetQuestionByContentItem(item.ContentItemId);
                        // use the post item to build the email subject/body/content (sub question for content item now)
                        var colEmail    = QaSettings.GetEmailCollection(Controller.GetQaPortalSettings(item.PortalId), item.PortalId);
                        var senderEmail = colEmail.Single(s => s.Key == Constants.EmailSettings.FromAddress.ToString()).Value;
                        //var urlBase = colEmail.Single(s => s.Key == Constants.EmailSettings.PrimaryUrl.ToString()).Value;
                        var answerTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.AnswerTemplate.ToString()).Value;
                        var ps             = new PortalSettings(item.PortalId);

                        var titleLink     = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/question/id/" + objQuestion.PostId + "/" + DotNetNuke.Common.Globals.glbDefaultPage;
                        var subscribeLink = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/subscriptions/" + DotNetNuke.Common.Globals.glbDefaultPage;

                        answerTemplate = answerTemplate.Replace("[AUTHOR]", item.PostCreatedDisplayName);
                        answerTemplate = answerTemplate.Replace("[TITLELINK]", titleLink);
                        answerTemplate = answerTemplate.Replace("[TITLE]", objQuestion.Title);
                        answerTemplate = answerTemplate.Replace("[BODY]", Utils.ProcessDisplayPostBody(item.Body));
                        answerTemplate = answerTemplate.Replace("[SUBSCRIBELINK]", subscribeLink);

                        var colSubscribers = Controller.GetSubscribersByQuestion(item.ParentId, (int)Constants.SubscriptionType.InstantPost, item.PortalId);
                        foreach (var subscriber in colSubscribers)
                        {
                            // send off the email one by one (same email to multiple subscribers)
                            Mail.SendMail(senderEmail, subscriber.Email, "", "", MailPriority.Normal,
                                          HtmlUtils.StripWhiteSpace(objQuestion.Title, true), MailFormat.Html, Encoding.UTF8, answerTemplate,
                                          "", Host.SMTPServer, Host.SMTPAuthentication, Host.SMTPUsername,
                                          Host.SMTPPassword, Host.EnableSMTPSSL);
                        }

                        strErrors = "Instant Post: Sent " + colSubscribers.Count + " emails - " + objQuestion.Title + "<br />";
                    }
                }
                else
                {
                    strErrors = "Instant Post: No new answers to email <br />";
                }

                // now we move onto comments
                var colComments = Controller.GetCommentsByDate(lastRunDate, currentRunDate);

                if (colComments.Count() > 0)
                {
                    foreach (var item in colComments)
                    {
                        var objPost         = Controller.GetPost(item.PostId, -1);
                        var ps              = new PortalSettings(objPost.PortalId);
                        var objQuestion     = objPost.ParentId == 0 ? objPost : Controller.GetQuestionByContentItem(objPost.ContentItemId);
                        var colEmail        = QaSettings.GetEmailCollection(Controller.GetQaPortalSettings(objQuestion.PortalId), objPost.PortalId);
                        var commentTemplate = colEmail.Single(s => s.Key == Constants.EmailSettings.CommentTemplate.ToString()).Value;
                        var senderEmail     = colEmail.Single(s => s.Key == Constants.EmailSettings.FromAddress.ToString()).Value;

                        var titleLink     = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/question/id/" + objQuestion.PostId + "/" + DotNetNuke.Common.Globals.glbDefaultPage;
                        var subscribeLink = "http://" + ps.DefaultPortalAlias + "/tabid/" + objQuestion.TabID + "/view/subscriptions/" + DotNetNuke.Common.Globals.glbDefaultPage;

                        commentTemplate = commentTemplate.Replace("[AUTHOR]", DotNetNuke.Entities.Users.UserController.GetUserById(objQuestion.PortalId, item.UserId).DisplayName);
                        commentTemplate = commentTemplate.Replace("[TITLELINK]", titleLink);
                        commentTemplate = commentTemplate.Replace("[TITLE]", objQuestion.Title);
                        commentTemplate = commentTemplate.Replace("[COMMENT]", Utils.ProcessDisplayPostBody(item.Comment));
                        commentTemplate = commentTemplate.Replace("[SUBSCRIBELINK]", subscribeLink);

                        var colSubscribers = Controller.GetSubscribersByQuestion(objQuestion.PostId, (int)Constants.SubscriptionType.InstantPost, objQuestion.PortalId);
                        foreach (var subscriber in colSubscribers)
                        {
                            // send off the email one by one (same email to multiple subscribers)
                            Mail.SendMail(senderEmail, subscriber.Email, "", "", MailPriority.Normal,
                                          HtmlUtils.StripWhiteSpace(objQuestion.Title, true), MailFormat.Html, Encoding.UTF8, commentTemplate,
                                          "", Host.SMTPServer, Host.SMTPAuthentication, Host.SMTPUsername,
                                          Host.SMTPPassword, Host.EnableSMTPSSL);
                        }
                        // we also have to remember to check if we emailed notification of a comment around this question already (only within this method, to avoid to comments on question being emailed 2x).
                        // also avoid emailing someone of their own comment
                    }
                }
                else
                {
                    strErrors = "Instant Post: No new comments to email <br />";
                }

                break;
            }

            return(strErrors);
        }