private void InitOverview() { if (mIssue.IssueIsABTest) { var abTest = ABTestInfoProvider.GetABTestInfoForIssue(mIssue.IssueID); if (abTest == null) { return; } var winnerIssueId = ValidationHelper.GetInteger(abTest.TestWinnerIssueID, 0); if (winnerIssueId == 0) { return; } var issueInForm = issueForm.EditedObject as IssueInfo; var winnerIssue = IssueInfoProvider.GetIssueInfo(winnerIssueId); if ((issueInForm != null) && (winnerIssue != null)) { issueInForm.IssueSubject = winnerIssue.IssueSubject; issueInForm.IssueSenderName = winnerIssue.IssueSenderName; issueInForm.IssueSenderEmail = winnerIssue.IssueSenderEmail; } } }
protected void Page_Load(object sender, EventArgs e) { PageTitle.TitleText = GetString("newsletter_issue_subscribersclicks.title"); linkId = QueryHelper.GetInteger("linkid", 0); if (linkId == 0) { RequestHelper.EndResponse(); } LinkInfo link = LinkInfoProvider.GetLinkInfo(linkId); EditedObject = link; IssueInfo issue = IssueInfoProvider.GetIssueInfo(link.LinkIssueID); EditedObject = issue; // Prevent accessing issues from sites other than current site if (issue.IssueSiteID != SiteContext.CurrentSiteID) { RedirectToResourceNotAvailableOnSite("Issue with ID " + link.LinkIssueID); } var where = new WhereCondition().Where("LinkID", QueryOperator.Equals, linkId); // Link's issue is the main A/B test issue if (issue.IssueIsABTest && !issue.IssueIsVariant) { // Get A/B test and its winner issue ID ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get ID of the same link from winner issue var winnerLink = LinkInfoProvider.GetLinks() .WhereEquals("LinkIssueID", test.TestWinnerIssueID) .WhereEquals("LinkTarget", link.LinkTarget) .WhereEquals("LinkDescription", link.LinkDescription) .TopN(1) .Column("LinkID") .FirstOrDefault(); if (winnerLink != null) { if (winnerLink.LinkID > 0) { // Add link ID of winner issue link where.Or(new WhereCondition().Where("LinkID", QueryOperator.Equals, winnerLink.LinkID)); } } } } where.And(new WhereCondition(fltOpenedBy.WhereCondition)); UniGrid.WhereCondition = where.WhereCondition; UniGrid.QueryParameters = where.Parameters; UniGrid.Pager.DefaultPageSize = PAGESIZE; UniGrid.Pager.ShowPageSize = false; UniGrid.FilterLimit = 1; UniGrid.OnExternalDataBound += UniGrid_OnExternalDataBound; }
protected void btnSend_Click(object sender, EventArgs e) { // Validate date/time if (dtpMailout.SelectedDateTime == DateTimeHelper.ZERO_TIME) { ShowError(GetString("newsletterissue_send.invaliddatetime")); return; } IssueInfo winner = (IssueInfo)EditedObject; int parentIssueId = winner.IssueVariantOfIssueID; // Get A/B test info ABTestInfo abi = ABTestInfoProvider.GetABTestInfoForIssue(parentIssueId); if (abi != null) { IssueInfo issue = IssueInfoProvider.GetIssueInfo(parentIssueId); // Check if winner was selected and sent if (abi.TestWinnerIssueID != 0) { if ((issue.IssueStatus == IssueStatusEnum.Finished) || (issue.IssueStatus == IssueStatusEnum.Sending)) { // Winner was already sent CloseDialogAndRefreshParent(); return; } } // Update A/B test info and winner selection task (if exist) abi.TestWinnerOption = ABTestWinnerSelectionEnum.Manual; NewsletterTasksManager.EnsureWinnerSelectionTask(abi, issue, false, DateTime.Now); abi.TestSelectWinnerAfter = 0; abi.TestWinnerSelected = DateTime.Now; abi.TestWinnerIssueID = winner.IssueID; ABTestInfoProvider.SetABTestInfo(abi); if ((issue != null) && (winner != null)) { var parentIssue = IssueInfoProvider.GetIssueInfo(parentIssueId); NewsletterSendingStatusModifier.ResetAllEmailsInQueueForIssue(parentIssue.IssueID); // Copy data from winner to parent IssueHelper.CopyWinningVariantIssueProperties(winner, issue); IssueInfoProvider.SetIssueInfo(issue); // Remove previous scheduled task of this issue NewsletterTasksManager.DeleteMailoutTask(issue.IssueGUID, issue.IssueSiteID); DateTime mailoutTime = dtpMailout.SelectedDateTime; Service.Resolve <IIssueScheduler>().ScheduleIssue(parentIssue, mailoutTime); } } // Close dialog and refresh parent page CloseDialogAndRefreshParent(); }
protected object UniGrid_OnExternalDataBound(object sender, string sourceName, object parameter) { switch (sourceName) { case "variantname": if (!isMainABTestIssue) { return(null); } IssueInfo issue = IssueInfoProvider.GetIssueInfo(ValidationHelper.GetInteger(parameter, 0)); string variantName = null; if (issue != null) { if (!issue.IssueIsVariant) { // Get variant name from the winner issue if (winnerIssue == null) { ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get A/B test winner variant winnerIssue = IssueInfoProvider.GetIssueInfo(test.TestWinnerIssueID); } } if (winnerIssue != null) { // Get variant name variantName = winnerIssue.IssueVariantName; } } else { // Get variant name variantName = issue.IssueVariantName; } } return(HTMLHelper.HTMLEncode(variantName)); default: return(parameter); } }
/// <summary> /// Reloads control data. /// </summary> /// <param name="forceReload">Indicates if force reload should be used</param> public override void ReloadData(bool forceReload) { if (StopProcessing && !forceReload) { return; } if (ForceReloadNeeded) { forceReload = true; ForceReloadNeeded = false; } int parentIssueId = 0; mParentIssue = IssueInfoProvider.GetOriginalIssue(IssueID); if (mParentIssue != null) { parentIssueId = mParentIssue.IssueID; } // Get A/B test configuration mABTest = ABTestInfoProvider.GetABTestInfoForIssue(parentIssueId); if (mABTest == null) { // Ensure A/B test object with default settings mABTest = new ABTestInfo() { TestIssueID = parentIssueId, TestSizePercentage = 50, TestWinnerOption = ABTestWinnerSelectionEnum.OpenRate, TestSelectWinnerAfter = 60 }; ABTestInfoProvider.SetABTestInfo(mABTest); } CurrentState = GetCurrentState(mParentIssue); InitControls(CurrentState, forceReload); ucMailout.ParentIssueID = parentIssueId; ucMailout.ReloadData(forceReload); InfoMessage = GetInfoMessage(CurrentState, mParentIssue, (mABTest != null ? mABTest.TestWinnerOption : ABTestWinnerSelectionEnum.OpenRate), GetPlannedMailoutTime(ucMailout.HighestMailoutTime)); // Init test group slider InitTestGroupSlider(mParentIssue, mABTest, forceReload); ucWO_OnChange(this, EventArgs.Empty); }
/// <summary> /// Reloads control data. /// </summary> /// <param name="forceReload">Indicates if force reload should be used</param> public override void ReloadData(bool forceReload) { if (StopProcessing && !forceReload) { return; } var parentIssueId = 0; mParentIssue = IssueInfoProvider.GetOriginalIssue(IssueID); if (mParentIssue != null) { parentIssueId = mParentIssue.IssueID; } // Get A/B test configuration mABTest = ABTestInfoProvider.GetABTestInfoForIssue(parentIssueId); if (mABTest == null) { // Ensure A/B test object with default settings mABTest = new ABTestInfo { TestIssueID = parentIssueId, TestSizePercentage = 50, TestWinnerOption = ABTestWinnerSelectionEnum.Manual }; ABTestInfo.Provider.Set(mABTest); } CurrentState = GetCurrentState(mParentIssue); if (mParentIssue.IssueForAutomation) { InitControlsForIssueUsedInAutomation(CurrentState, forceReload); } else { InitControls(CurrentState, forceReload); } ucMailout.ParentIssueID = parentIssueId; ucMailout.ReloadData(forceReload); InfoMessage = GetInfoMessage(CurrentState, mParentIssue, mABTest?.TestWinnerOption ?? ABTestWinnerSelectionEnum.Manual); // Init test group slider InitTestGroupSlider(mParentIssue, mABTest, forceReload); }
/// <summary> /// Deletes an issue specified by its ID (if authorized). /// </summary> /// <param name="issueId">Issue's ID</param> private static void DeleteIssue(int issueId) { var issue = GetIssueOrRedirect(issueId); // User has to have both destroy and issue privileges to be able to delete the issue. if (!issue.CheckPermissions(PermissionsEnum.Delete, SiteContext.CurrentSiteName, MembershipContext.AuthenticatedUser)) { RedirectToAccessDenied(issue.TypeInfo.ModuleName, "AuthorIssues"); } if (issue.IssueIsABTest) { var abTest = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); NewsletterTasksManager.DeleteWinnerSelectionTask(abTest); } IssueInfo.Provider.Delete(issue); }
public override void ReloadData(bool forceReload) { if (StopProcessing && !forceReload) { return; } InitControls(forceReload); // Javascript for handling winner mailout time string scriptBlock = string.Format(@"function SelWinner(id) {{ modalDialog('{0}?issueid=' + id, 'NewsletterWinnerMailout', '400px', '300px'); return false; }} function ShowOpenedBy(id) {{ modalDialog('{1}?issueid=' + id, 'NewsletterIssueOpenedBy', '900px', '700px'); return false; }} function ViewClickedLinks(id) {{ modalDialog('{2}?issueid=' + id, 'NewsletterTrackedLinks', '900px', '700px'); return false; }}", ResolveUrl(@"~\CMSModules\Newsletters\Tools\Newsletters\Newsletter_Issue_WinnerMailout.aspx"), ResolveUrl(@"~\CMSModules\Newsletters\Tools\Newsletters\Newsletter_Issue_OpenedBy.aspx"), ResolveUrl(@"~\CMSModules\Newsletters\Tools\Newsletters\Newsletter_Issue_TrackedLinks.aspx")); ScriptHelper.RegisterDialogScript(Page); ScriptHelper.RegisterClientScriptBlock(this, GetType(), "Actions", scriptBlock, true); // Register handlers grdElem.OnExternalDataBound -= new OnExternalDataBoundEventHandler(grdElem_OnExternalDataBound); grdElem.OnExternalDataBound += new OnExternalDataBoundEventHandler(grdElem_OnExternalDataBound); grdElem.GridView.RowDataBound -= new GridViewRowEventHandler(GridView_RowDataBound); grdElem.GridView.RowDataBound += new GridViewRowEventHandler(GridView_RowDataBound); // Get winner ID if any ABTestInfo abi = ABTestInfoProvider.GetABTestInfoForIssue(ParentIssueID); if (abi != null) { WinnerIssueID = abi.TestWinnerIssueID; } grdElem.WhereCondition = GetWhereCondition(ParentIssueID, false); grdElem.ShowActionsMenu = false; grdElem.ShowObjectMenu = false; if (!ShowSelectWinnerAction) { grdElem.GridActions = null; } grdElem.ReloadData(); }
public override void ReloadData(bool forceReload) { if (StopProcessing && !forceReload) { return; } InitControls(forceReload); // Javascript for handling winner mailout time var scriptBlock = string.Format(@"function SelWinner(id) {{ modalDialog('{0}?objectid=' + id, 'NewsletterWinnerMailout', '700px', '425px'); return false; }}", ResolveUrl(@"~\CMSModules\Newsletters\Tools\Newsletters\Newsletter_Issue_WinnerMailout.aspx")); ScriptHelper.RegisterDialogScript(Page); ScriptHelper.RegisterClientScriptBlock(this, GetType(), "Actions", scriptBlock, true); ScriptHelper.RegisterTooltip(Page); // Register handlers grdElem.OnExternalDataBound -= grdElem_OnExternalDataBound; grdElem.OnExternalDataBound += grdElem_OnExternalDataBound; grdElem.GridView.RowDataBound -= GridView_RowDataBound; grdElem.GridView.RowDataBound += GridView_RowDataBound; // Get winner ID if any var abTestInfo = ABTestInfoProvider.GetABTestInfoForIssue(ParentIssueID); if (abTestInfo != null) { WinnerIssueID = abTestInfo.TestWinnerIssueID; } mBounceMonitoringEnabled = NewsletterHelper.MonitorBouncedEmails(SiteContext.CurrentSiteName); grdElem.OrderBy = "IssueVariantName, IssueID"; grdElem.WhereCondition = GetWhereCondition(ParentIssueID, false); grdElem.ShowActionsMenu = false; grdElem.ShowObjectMenu = false; if (!ShowSelectWinnerAction) { grdElem.GridActions = null; } grdElem.ReloadData(); }
/// <summary> /// In the parent issue is stored "SentEmail" amount of all variants and the remainder, /// so the remainder amount have to be computed by subtraction of all sent amounts /// from particular variants. /// </summary> /// <param name="parentIssue">Parent issue</param> /// <param name="variantIssue">Current variant</param> /// <returns></returns> private int CalculateVariantSentEmails(IssueInfo parentIssue, IssueInfo variantIssue) { if ((parentIssue == null) || (variantIssue == null)) { return(0); } if (IncludeAllVariants) { return(GetSentOrDelivered(parentIssue)); } // If the winner has not been selected yet, or the selected variant is not the winner // return SentEmails of the current variant if (parentIssue.IssueID != variantIssue.IssueID) { return(variantIssue.IssueSentEmails); } var abTest = ABTestInfoProvider.GetABTestInfoForIssue(parentIssue.IssueID); if (abTest == null) { return(0); } // If variantIssue equals parentIssue it means that winner variant was selected, but the // filter has returned the parent variant, and we need winner variant object // For the winner variant is returned the sum of variant SentEmail amount and the remainder SentEmail amount. // See the "Summary" section for the domain specification. var sentSumFromRemainingVariants = IssueInfoProvider.GetIssues() .Column(new AggregatedColumn(AggregationType.Sum, "IssueSentEmails")) .WhereEquals("IssueVariantOfIssueID", parentIssue.IssueID) .And() .WhereNotEquals("IssueID", abTest.TestWinnerIssueID) .GetScalarResult(0); return(parentIssue.IssueSentEmails - sentSumFromRemainingVariants); }
/// <summary> /// Gets number of opened e-mails of winner variant issue. /// </summary> /// <param name="issueId">ID of parent issue</param> private int GetWinnerVariantOpenes(int issueId) { int openedEmails = 0; ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issueId); if ((test != null) && (test.TestWinnerIssueID > 0)) { IssueInfo winner = IssueInfoProvider.GetIssueInfo(test.TestWinnerIssueID); if (winner != null) { // Get opened emails count from winner issue openedEmails += winner.IssueOpenedEmails; if (mOnlineMarketingEnabled) { // Get number of emails opened by contact group and persona members openedEmails += OpenedEmailInfoProvider.GetMultiSubscriberOpenedIssueActivityCount(winner.IssueID); } } } return(openedEmails); }
/// <summary> /// Saves current newsletter settings. /// </summary> public bool SaveIssue() { try { switch (CurrentState) { case STATE_WAITING_TO_SEND_PAGE: case STATE_WAITING_TO_SEND_WIZARD: case STATE_TEST_READY_FOR_SENDING: case STATE_TEST_WAITING_TO_SEL_WINNER: if (abTest == null) { abTest = ABTestInfoProvider.GetABTestInfoForIssue(parentIssue.IssueID); } // Get A/B test settings from controls bool abTestChanged = SaveABTestInfo(abTest); if (abTest == null) { return(false); } if (abTest.TestWinnerOption != ABTestWinnerSelectionEnum.Manual) { // Check minimal time interval if (abTest.TestSelectWinnerAfter < 5) { ErrorMessage = GetString("newsletterissue_send.saveissuewrongwinnerselectioninterval"); return(false); } } // Check if test options has changed if (abTestChanged) { if (abTest.TestWinnerIssueID > 0) { // Options has been changed => reset previously selected winner IssueInfoProvider.DeleteMailoutTask(parentIssue.IssueGUID, parentIssue.IssueSiteID); abTest.TestWinnerIssueID = 0; abTest.TestWinnerSelected = DateTimeHelper.ZERO_TIME; // Hide/reload winner selection in issue mail-out grid ucMailout.ReloadData(false); } IssueInfoProvider.SetIssueInfo(parentIssue); } ABTestInfoProvider.SetABTestInfo(abTest); IssueHelper.EnsureWinnerSelectionTask(abTest, parentIssue, (CurrentState == STATE_TEST_WAITING_TO_SEL_WINNER), ucMailout.HighestMailoutTime); // Update info message for parent control int currentState = GetCurrentState(parentIssue); InfoMessage = GetInfoMessage(currentState, parentIssue, abTest.TestWinnerOption, GetPlannedMailoutTime(ucMailout.HighestMailoutTime)); return(true); case STATE_TEST_FINISHED: ErrorMessage = GetString("newsletterissue_send.saveissuehasbeensent"); break; } } catch (Exception e) { ErrorMessage = e.Message; return(false); } return(true); }
protected DataSet GetLinks(string completeWhere, string currentOrder, int currentTopN, string columns, int currentOffset, int currentPageSize, ref int totalRecords) { // Default where condition WhereCondition whereIssues = new WhereCondition().WhereEquals("LinkIssueID", issueID); isMainABTestIssue = isMainABTestIssue && (issueID == IssueID); int winnerIssueId = 0; if (IncludeAllVariants && isABTest) { // Get all variants var issueIDs = IssueInfoProvider.GetIssues() .Column("IssueID") .WhereEquals("IssueID", IssueID) .Or() .WhereEquals("IssueVariantOfIssueID", IssueID).GetListResult <Int32>(); // Include all links for all variants whereIssues = new WhereCondition().WhereIn("LinkIssueID", issueIDs); } else if (IncludeWinnerStatistics && isMainABTestIssue) { var test = ABTestInfoProvider.GetABTestInfoForIssue(issueID); if (test != null) { // Get winner variant issue ID winnerIssueId = test.TestWinnerIssueID; } if (winnerIssueId > 0) { // Include winner issue whereIssues = whereIssues.Or().WhereEquals("LinkIssueID", winnerIssueId); } } // Get links with clicks statistics for issue(s) var query = LinkInfoProvider.GetLinks() .Columns( new QueryColumn("LinkID"), new QueryColumn("LinkIssueID"), new QueryColumn("LinkTarget"), new QueryColumn("LinkDescription"), new QueryColumn("LinkOutdated"), // Get total and unique clicks new AggregatedColumn(AggregationType.Count, "DISTINCT(ClickedLinkEmail)").As("UniqueClicks"), new AggregatedColumn(AggregationType.Count, "ClickedLinkEmail").As("TotalClicks") ) .Where(whereIssues) .And() .Where(fltLinks.WhereCondition) .Source(s => s.LeftJoin <ClickedLinkInfo>("LinkID", "ClickedLinkNewsletterLinkID")) .GroupBy("LinkID", "LinkIssueID", "LinkTarget", "LinkDescription", "LinkOutdated"); if ((winnerIssueId > 0) || IncludeAllVariants) { // Aggregate same links (LinkTarget, LinkDescription, LinkOutdated) from various variants (variant + winner OR all variants) query = query.AsNested() .Columns( new QueryColumn("LinkTarget"), new QueryColumn("LinkDescription"), new QueryColumn("LinkOutdated"), // Get ID of main issue link (grater than variant link ID) new AggregatedColumn(AggregationType.Max, "LinkID").As("LinkID"), // Get total and unique clicks (sum variants) new AggregatedColumn(AggregationType.Sum, "UniqueClicks").As("UniqueClicks"), new AggregatedColumn(AggregationType.Sum, "TotalClicks").As("TotalClicks") ) .GroupBy("LinkTarget", "LinkDescription", "LinkOutdated"); if (DisplayOnlyClickedLinks) { query = query.Having(x => x.WhereGreaterThan(new AggregatedColumn(AggregationType.Sum, "UniqueClicks"), 0)); } } else if (DisplayOnlyClickedLinks) { query = query.Having(x => x.WhereGreaterThan(new AggregatedColumn(AggregationType.Count, "DISTINCT(ClickedLinkEmail)").As("UniqueClicks"), 0)); } if (TopN > 0) { query = query.TopN(TopN); } query = query.OrderByDescending("UniqueClicks"); return(query.Result); }
protected object UniGrid_OnExternalDataBound(object sender, string sourceName, object parameter) { DataRowView row = null; if (parameter is DataRowView) { row = (DataRowView)parameter; } int subscriberId = 0; switch (sourceName) { case "name": subscriberId = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(row.Row, "SubscriberID"), 0); string name = null; if (subscriberId == 0) { // Get full name for contact group member (contact) name = ValidationHelper.GetString(DataHelper.GetDataRowValue(row.Row, "SubscriberFullName"), string.Empty); // Return encoded name return(HTMLHelper.HTMLEncode(name)); } else { // Add the field transformation control that handles the translation var tr = new ObjectTransformation("newsletter.subscriber", subscriberId); tr.Transformation = "SubscriberFullName"; return(tr); } case "email": subscriberId = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(row.Row, "SubscriberID"), 0); string email = null; if (subscriberId == 0) { // Get email for contact group member (contact) email = ValidationHelper.GetString(DataHelper.GetDataRowValue(row.Row, "SubscriberEmail"), string.Empty); } else { SubscriberInfo subscriber = SubscriberInfoProvider.GetSubscriberInfo(subscriberId); if (subscriber != null) { if (subscriber.SubscriberType == null) { // Get email for classic subscriber email = subscriber.SubscriberEmail; } else { switch (subscriber.SubscriberType) { case UserInfo.OBJECT_TYPE: UserInfo user = UserInfoProvider.GetUserInfo(subscriber.SubscriberRelatedID); if (user != null) { // Get email for user subscriber email = user.Email; } break; case PredefinedObjectType.CONTACT: DataSet ds = ModuleCommands.OnlineMarketingGetContactForNewsletters(subscriber.SubscriberRelatedID, "ContactEmail"); if (!DataHelper.DataSourceIsEmpty(ds)) { // Get email from contact subscriber email = ValidationHelper.GetString(ds.Tables[0].Rows[0]["ContactEmail"], string.Empty); } break; } } } } if (!string.IsNullOrEmpty(email)) { // Return encoded email email = HTMLHelper.HTMLEncode(email); } return(email); case "variantname": if (!isMainABTestIssue) { return(null); } IssueInfo issue = IssueInfoProvider.GetIssueInfo(ValidationHelper.GetInteger(parameter, 0)); string variantName = null; if (issue != null) { if (!issue.IssueIsVariant) { // Get varinat name from the winner issue if (winnerIssue == null) { ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get A/B test winner variant winnerIssue = IssueInfoProvider.GetIssueInfo(test.TestWinnerIssueID); } } if (winnerIssue != null) { // Get variant name variantName = winnerIssue.IssueVariantName; } } else { // Get variant name variantName = issue.IssueVariantName; } } return(variantName); default: return(parameter); } }
protected void variantDailog_OnDeleteVariant(object sender, EventArgs e) { if (Variants.Count <= 0) { return; } // Allow modifying issues in idle state only IssueInfo parentIssue = IssueInfoProvider.GetOriginalIssue(IssueID); if ((parentIssue == null) || (parentIssue.IssueStatus != IssueStatusEnum.Idle)) { return; } int currVariant = CurrentVariant; if (Variants.Count > 2) { IssueInfoProvider.DeleteIssueInfo(Variants[currVariant].IssueID); Variants.RemoveAt(currVariant); RaiseVariantDeleted(); } else { if (Variants.Count == 2) { // Remove variant IssueInfoProvider.DeleteIssueInfo(Variants[currVariant].IssueID); Variants.RemoveAt(currVariant); } // Get remaining variant IssueABVariantItem issueVariant = Variants[0]; Variants.Clear(); IssueInfo issue = IssueInfoProvider.GetIssueInfo(issueVariant.IssueID); if (issue != null) { // Transfer all data from child to parent and delete child const string ignoredColumns = ";issueid;issueguid;issuevariantname;"; foreach (string column in parentIssue.ColumnNames) { if (!ignoredColumns.Contains(String.Format(";{0};", column.ToLowerCSafe()))) { parentIssue.SetValue(column, issue.GetValue(column)); } } parentIssue.IssueIsABTest = false; parentIssue.IssueVariantName = null; parentIssue.IssueVariantOfIssueID = 0; IssueInfoProvider.SetIssueInfo(parentIssue); // Delete files from parent issue if any MetaFileInfoProvider.DeleteFiles(parentIssue.IssueID, IssueInfo.OBJECT_TYPE, ObjectAttachmentsCategories.ISSUE); MetaFileInfoProvider.DeleteFiles(parentIssue.IssueID, IssueInfo.OBJECT_TYPE_VARIANT, ObjectAttachmentsCategories.ISSUE); // Move attachments (meta files) from child to parent MetaFileInfoProvider.MoveMetaFiles(issue.IssueID, parentIssue.IssueID, IssueInfo.OBJECT_TYPE_VARIANT, ObjectAttachmentsCategories.ISSUE, IssueInfo.OBJECT_TYPE, ObjectAttachmentsCategories.ISSUE); MetaFileInfoProvider.MoveMetaFiles(issue.IssueID, parentIssue.IssueID, IssueInfo.OBJECT_TYPE, ObjectAttachmentsCategories.ISSUE, IssueInfo.OBJECT_TYPE, ObjectAttachmentsCategories.ISSUE); // Delete last variant IssueInfoProvider.DeleteIssueInfo(issue); OriginalIssueID = parentIssue.IssueID; // A/B variants have been deleted => deleting A/B test itself ABTestInfo abi = ABTestInfoProvider.GetABTestInfoForIssue(OriginalIssueID); ABTestInfoProvider.DeleteABTestInfo(abi); } RaiseVariantDeleted(); } }
/// <summary> /// Saves current newsletter settings. /// </summary> public bool SaveIssue() { try { switch (CurrentState) { case VariantStatusEnum.WaitingToSend: case VariantStatusEnum.ReadyForSending: case VariantStatusEnum.ReadyForTesting: case VariantStatusEnum.WaitingToSelectWinner: if (mABTest == null) { mABTest = ABTestInfoProvider.GetABTestInfoForIssue(mParentIssue.IssueID); } // Get A/B test settings from controls var abTestChanged = SaveABTestInfo(mABTest); if (mABTest == null) { return(false); } if (mABTest.TestWinnerOption != ABTestWinnerSelectionEnum.Manual) { // Check minimal time interval if (mABTest.TestSelectWinnerAfter < 5) { ErrorMessage = GetString("newsletterissue_send.saveissuewrongwinnerselectioninterval"); return(false); } } // Check if test options has changed if (abTestChanged && mABTest.TestWinnerIssueID > 0) { // Options has been changed => reset previously selected winner NewsletterTasksManager.DeleteMailoutTask(mParentIssue.IssueGUID, mParentIssue.IssueSiteID); mABTest.TestWinnerIssueID = 0; mABTest.TestWinnerSelected = DateTimeHelper.ZERO_TIME; // Hide/reload winner selection in issue mail-out grid ucMailout.ReloadData(false); } ABTestInfo.Provider.Set(mABTest); if (CurrentState == VariantStatusEnum.WaitingToSelectWinner) { NewsletterTasksManager.EnsureWinnerSelectionTask(mABTest, mParentIssue, true, ucMailout.HighestMailoutTime); } // Update info message for parent control var currentState = GetCurrentState(mParentIssue); InfoMessage = GetInfoMessage(currentState, mParentIssue, mABTest.TestWinnerOption); return(true); case VariantStatusEnum.Finished: ErrorMessage = GetString("newsletterissue_send.saveissuehasbeensent"); break; } } catch (Exception e) { ErrorMessage = e.Message; return(false); } return(true); }
protected void Page_Load(object sender, EventArgs e) { CurrentMaster.Title.TitleText = GetString("newsletter_issue_subscribersclicks.title"); CurrentMaster.Title.TitleImage = GetImageUrl("CMSModules/CMS_Newsletter/ViewParticipants.png"); linkId = QueryHelper.GetInteger("linkid", 0); if (linkId == 0) { RequestHelper.EndResponse(); } LinkInfo link = LinkInfoProvider.GetLinkInfo(linkId); EditedObject = link; IssueInfo issue = IssueInfoProvider.GetIssueInfo(link.LinkIssueID); EditedObject = issue; // Prevent accessing issues from sites other than current site if (issue.IssueSiteID != CMSContext.CurrentSiteID) { RedirectToResourceNotAvailableOnSite("Issue with ID " + link.LinkIssueID); } QueryDataParameters parameters = null; string where = string.Empty; // Link's issue is the main A/B test issue if (issue.IssueIsABTest && !issue.IssueIsVariant) { // Prepare base where condition where = "LinkID IN (" + link.LinkID.ToString(); // Get A/B test and its winner issue ID ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get ID of the same link from winner issue InfoDataSet <LinkInfo> winnerLink = LinkInfoProvider.GetLinks(string.Format("LinkIssueID={0} AND LinkTarget=N'{1}' AND LinkDescription=N'{2}'", test.TestWinnerIssueID, link.LinkTarget, link.LinkDescription), null, 1, "LinkID"); if (!DataHelper.DataSourceIsEmpty(winnerLink)) { string winnerLinkID = ValidationHelper.GetString(DataHelper.GetDataRowValue(winnerLink.Tables[0].Rows[0], "LinkID"), string.Empty); if (!string.IsNullOrEmpty(winnerLinkID)) { // Add link ID of winner issue link where += "," + winnerLinkID; } } } // Close where condition where += ")"; } else { // Filter by Link ID (from querystring) parameters = new QueryDataParameters(); parameters.Add("@LinkID", linkId); } UniGrid.QueryParameters = parameters; UniGrid.WhereCondition = SqlHelperClass.AddWhereCondition(fltOpenedBy.WhereCondition, where); UniGrid.Pager.DefaultPageSize = PAGESIZE; UniGrid.Pager.ShowPageSize = false; UniGrid.FilterLimit = 1; UniGrid.OnExternalDataBound += UniGrid_OnExternalDataBound; }
protected void Page_Load(object sender, EventArgs e) { PageTitle.TitleText = GetString("newsletter_issue_subscribersclicks.title"); linkId = QueryHelper.GetInteger("linkid", 0); if (linkId == 0) { RequestHelper.EndResponse(); } LinkInfo link = LinkInfoProvider.GetLinkInfo(linkId); EditedObject = link; IssueInfo issue = IssueInfoProvider.GetIssueInfo(link.LinkIssueID); EditedObject = issue; // Prevent accessing issues from sites other than current site if (issue.IssueSiteID != SiteContext.CurrentSiteID) { RedirectToResourceNotAvailableOnSite("Issue with ID " + link.LinkIssueID); } var listingWhereCondition = new WhereCondition().WhereEquals("ClickedLinkNewsletterLinkID", linkId); // Link's issue is the main A/B test issue if (issue.IssueIsABTest && !issue.IssueIsVariant) { // Get A/B test and its winner issue ID ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get ID of the same link from winner issue var winnerLink = LinkInfoProvider.GetLinks() .WhereEquals("LinkIssueID", test.TestWinnerIssueID) .WhereEquals("LinkTarget", link.LinkTarget) .WhereEquals("LinkDescription", link.LinkDescription) .TopN(1) .Column("LinkID") .FirstOrDefault(); if (winnerLink != null) { if (winnerLink.LinkID > 0) { // Add link ID of winner issue link listingWhereCondition.Or(new WhereCondition().WhereEquals("ClickedLinkNewsletterLinkID", winnerLink.LinkID)); } } } } UniGrid.Pager.DefaultPageSize = PAGESIZE; UniGrid.Pager.ShowPageSize = false; UniGrid.FilterLimit = 1; fltOpenedBy.EmailColumn = "ClickedLinkEmail"; // Get click count by email UniGrid.DataSource = ClickedLinkInfoProvider.GetClickedLinks() .Columns( new QueryColumn("ClickedLinkEmail"), new AggregatedColumn(AggregationType.Count, null).As("ClickCount") ) .GroupBy("ClickedLinkEmail") .Where(listingWhereCondition) .And() .Where(fltOpenedBy.WhereCondition) .OrderByDescending("ClickCount") .Result; }
/// <summary> /// Reloads control data. /// </summary> /// <param name="forceReload">Indicates if force reload should be used</param> public override void ReloadData(bool forceReload) { if (StopProcessing && !forceReload) { return; } if (ForceReloadNeeded) { forceReload = true; ForceReloadNeeded = false; } int parentIssueId = 0; parentIssue = IssueInfoProvider.GetOriginalIssue(IssueID); if (parentIssue != null) { parentIssueId = parentIssue.IssueID; } // Get A/B test configuration abTest = ABTestInfoProvider.GetABTestInfoForIssue(parentIssueId); if (abTest == null) { // Ensure A/B test object with default settings abTest = new ABTestInfo() { TestIssueID = parentIssueId, TestSizePercentage = 50, TestWinnerOption = ABTestWinnerSelectionEnum.OpenRate, TestSelectWinnerAfter = 60 }; ABTestInfoProvider.SetABTestInfo(abTest); } CurrentState = GetCurrentState(parentIssue); InitControls(CurrentState, forceReload); ucMailout.ParentIssueID = parentIssueId; ucMailout.ReloadData(forceReload); InfoMessage = GetInfoMessage(CurrentState, parentIssue, (abTest != null ? abTest.TestWinnerOption : ABTestWinnerSelectionEnum.OpenRate), GetPlannedMailoutTime(ucMailout.HighestMailoutTime)); // Init test group slider List <IssueABVariantItem> variants = IssueHelper.GetIssueVariants(parentIssue, null); ucGroupSlider.Variants = variants; bool allVariantsSent = true; if (variants != null) { allVariantsSent = variants.TrueForAll(delegate(IssueABVariantItem item) { return(item.IssueStatus == IssueStatusEnum.Finished); }); } if ((parentIssue.IssueStatus == IssueStatusEnum.Finished) || allVariantsSent) { // Issue was sent long time ago => get number of subscribers from issue properties instead of current number of subscribers int perVariantEmails = 1; if (abTest != null) { perVariantEmails = abTest.TestNumberPerVariantEmails; } ucGroupSlider.NumberOfTestSubscribers = ucGroupSlider.Variants.Count * perVariantEmails; if (parentIssue.IssueStatus == IssueStatusEnum.Finished) { // Issue was sent => get number of subscribers from number of sent issues ucGroupSlider.NumberOfSubscribers = parentIssue.IssueSentEmails; } else { // Only variants was sent => get current number of subscribers ucGroupSlider.NumberOfSubscribers = GetEmailAddressCount(parentIssue.IssueNewsletterID, parentIssue.IssueSiteID); } } else { ucGroupSlider.NumberOfSubscribers = GetEmailAddressCount(parentIssue.IssueNewsletterID, parentIssue.IssueSiteID); } if (forceReload || !ucGroupSlider.Enabled) { ucGroupSlider.CurrentSize = (abTest != null ? abTest.TestSizePercentage : 10); } ucGroupSlider.ReloadData(forceReload); ucWO_OnChange(this, EventArgs.Empty); }
protected object UniGrid_OnExternalDataBound(object sender, string sourceName, object parameter) { switch (sourceName) { case "clickrate": case "uniqueclicks": case "totalclicks": { DataRowView row = (DataRowView)parameter; int value = 0; if (sourceName.EqualsCSafe("totalclicks", true)) { // Get total clicks value value = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(row.Row, "TotalClicks"), 0); } else { // Get unique clicks value value = ValidationHelper.GetInteger(DataHelper.GetDataRowValue(row.Row, "UniqueClicks"), 0); } // If A/B test links are shown... if (isMainABTestIssue) { // Get selected issue (main or variant) IssueInfo issue = IssueInfoProvider.GetIssueInfo(issueId); if ((issue != null) && (!issue.IssueIsVariant)) { // Get current link target and description string linkTarget = ValidationHelper.GetString(DataHelper.GetDataRowValue(row.Row, "LinkTarget"), string.Empty); string linkDescription = ValidationHelper.GetString(DataHelper.GetDataRowValue(row.Row, "LinkDescription"), string.Empty); // If the issue is main issue add winner variant statistics if (DataHelper.DataSourceIsEmpty(winnerData) && (UniGrid.InfoObject != null)) { int winnerIssueId = 0; ABTestInfo test = ABTestInfoProvider.GetABTestInfoForIssue(issue.IssueID); if (test != null) { // Get winner variant issue ID winnerIssueId = test.TestWinnerIssueID; } winnerData = UniGrid.InfoObject.GetData(null, "IssueID=" + winnerIssueId, null, -1, "LinkTarget,LinkDescription,UniqueClicks,TotalClicks", false); } if (!DataHelper.DataSourceIsEmpty(winnerData)) { // Select data with matching link target and description DataRow[] selectedRows = winnerData.Tables[0].Select(string.Format("LinkTarget='{0}' AND LinkDescription='{1}'", linkTarget, linkDescription)); if ((selectedRows != null) && (selectedRows.Length > 0)) { if (sourceName.EqualsCSafe("totalclicks", true)) { // Get total clicks value value += ValidationHelper.GetInteger(DataHelper.GetDataRowValue(selectedRows[0], "TotalClicks"), 0); // Store if grid action should be visible (hide it if total clicks is lower than 0) showGridAction.Add(ValidationHelper.GetInteger(DataHelper.GetDataRowValue(row.Row, "LinkID"), 0), (value > 0)); } else { // Get unique clicks value value += ValidationHelper.GetInteger(DataHelper.GetDataRowValue(selectedRows[0], "UniqueClicks"), 0); } } } } } if (sourceName.EqualsCSafe("clickrate", true)) { // Return formated click rate return(string.Format("{0:F0}", (ValidationHelper.GetDouble(value, 0) / sentEmails) * 100)); } else { // Return unique or total clicks return(value); } } case "linktarget": return(string.Format(@"<a href=""#"" onclick=""OpenTarget('{0}')"">{1}</a>", parameter, HTMLHelper.HTMLEncode(TextHelper.LimitLength(parameter.ToString(), 50)))); case "linktargettooltip": return(HTMLHelper.HTMLEncode(parameter.ToString())); case "linkdescription": return(HTMLHelper.HTMLEncode(TextHelper.LimitLength(parameter.ToString(), 25))); case "linkdescriptiontooltip": return(HTMLHelper.HTMLEncode(parameter.ToString())); case "view": if (sender is ImageButton) { ImageButton imageButton = sender as ImageButton; // Register for prerender event to hide actions for links without any clicks imageButton.PreRender += ActionButton_PreRender; } return(sender); case "deleteoutdated": if (sender is ImageButton) { ImageButton imageButton = sender as ImageButton; GridViewRow gvr = parameter as GridViewRow; if (gvr != null) { DataRowView drv = gvr.DataItem as DataRowView; if (drv != null) { bool isOutdated = ValidationHelper.GetBoolean(drv["LinkOutdated"], false); if (!isOutdated) { // Hide delete button for links that are not outdated imageButton.Style.Add(HtmlTextWriterStyle.Display, "none"); } } } } return(sender); default: return(parameter); } }
protected void btnSend_Click(object sender, EventArgs e) { // Validate date/time (blank date/time textbox is allowed) if ((dtpMailout.SelectedDateTime == DateTimeHelper.ZERO_TIME) && !String.IsNullOrEmpty(dtpMailout.DateTimeTextBox.Text.Trim())) { ShowError(GetString("newsletterissue_send.invaliddatetime")); return; } IssueInfo winner = (IssueInfo)EditedObject; int parentIssueId = winner.IssueVariantOfIssueID; // Get A/B test info ABTestInfo abi = ABTestInfoProvider.GetABTestInfoForIssue(parentIssueId); if (abi != null) { IssueInfo issue = IssueInfoProvider.GetIssueInfo(parentIssueId); // Check if winner was selected and sent if (abi.TestWinnerIssueID != 0) { if ((issue.IssueStatus == IssueStatusEnum.Finished) || (issue.IssueStatus == IssueStatusEnum.Sending)) { // Winner was already sent CloseDialogAndRefreshParent(); return; } } // Update A/B test info and winner selection task (if exist) abi.TestWinnerOption = ABTestWinnerSelectionEnum.Manual; IssueHelper.EnsureWinnerSelectionTask(abi, issue, false); abi.TestSelectWinnerAfter = 0; abi.TestWinnerSelected = DateTime.Now; abi.TestWinnerIssueID = winner.IssueID; ABTestInfoProvider.SetABTestInfo(abi); if ((issue != null) && (winner != null)) { // Copy data from winner to parent IssueHelper.CopyIssueProperties(winner, issue, "issuesubject;issuetext;issuetemplateid;issueshowinnewsletterarchive;issuesendername;issuesenderemail"); IssueInfoProvider.SetIssueInfo(issue); // Remove previous scheduled task of this issue IssueInfoProvider.DeleteMailoutTask(issue.IssueGUID, issue.IssueSiteID); DateTime mailoutTime = dtpMailout.SelectedDateTime; if (mailoutTime < DateTime.Now) { // Send parent issue now IssueInfoProvider.SendIssue(parentIssueId, DateTime.Now); } else { // Send winner at specified time IssueInfoProvider.SendIssue(parentIssueId, mailoutTime); } } } // Close dialog and refresh parent page CloseDialogAndRefreshParent(); }