using System; using System.Data; using System.Web; using CMS.CMSHelper; using CMS.DataEngine; using CMS.GlobalHelper; using CMS.OnlineMarketing; using CMS.SettingsProvider; using CMS.SiteProvider; using CMS.DocumentEngine; using CMS.WorkflowEngine; using CMS.UIControls; using CMS.Newsletter; using CMS.WebAnalytics; /// /// Online marketing functions. /// public static class OnlineMarketingFunctions { /// /// Returns contact's last activity of specified activity type. /// /// Contact info object /// Activity type public static ActivityInfo LastActivityOfType(object contact, object activityType) { ContactInfo ci = (ContactInfo)contact; string type = ValidationHelper.GetString(activityType, string.Empty); if (ci != null) { return ActivityInfoProvider.GetContactsLastActivity(ci.ContactID, type); } return null; } /// /// Returns contact's first activity of specified activity type. /// /// Contact info object /// Activity type public static ActivityInfo FirstActivityOfType(object contact, object activityType) { ContactInfo ci = (ContactInfo)contact; string type = ValidationHelper.GetString(activityType, string.Empty); if (ci != null) { return ActivityInfoProvider.GetContactsFirstActivity(ci.ContactID, type); } return null; } /// /// Returns TRUE if the contact is in any/all specified contact group(s) on current site. /// /// Contact info object /// Contact group name(s) separated by semicolon /// If true contact has to be in all specified groups, if false, it is sufficient if the contact is in any of the specified groups. public static bool IsInContactGroup(object contact, object contactGroupName, bool allGroups) { ContactInfo ci = (ContactInfo)contact; string groupNames = ValidationHelper.GetString(contactGroupName, string.Empty); int siteId = CMSContext.CurrentSiteID; if ((ci != null) && (siteId > 0) && (!string.IsNullOrEmpty(groupNames))) { string where = null; string[] names = groupNames.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string groupName in names) { where = SqlHelperClass.AddWhereCondition("ContactGroupName='" + SqlHelperClass.GetSafeQueryString(groupName, false) + "'", where, "OR"); } where = SqlHelperClass.AddWhereCondition("ContactGroupSiteID=" + siteId + " AND ContactGroupID IN (SELECT ContactGroupMemberContactGroupID FROM OM_ContactGroupMember WHERE ContactGroupMemberRelatedID=" + ci.ContactID + " AND ContactGroupMemberType=0)", where); // Get contact group ID if the name matches and contact is member of the group DataSet ds = ContactGroupInfoProvider.GetContactGroups(where, null, 0, "DISTINCT ContactGroupName"); if (allGroups) { return ds.Tables[0].Rows.Count >= names.Length; } else { return !DataHelper.DataSourceIsEmpty(ds); } } return false; } /// /// Returns contact's points in specified score on current site. /// /// Contact info object /// Score name public static int GetScore(object contact, object scoreName) { ContactInfo ci = (ContactInfo)contact; string score = ValidationHelper.GetString(scoreName, string.Empty); int siteId = CMSContext.CurrentSiteID; if ((ci != null) && (siteId > 0) && (!string.IsNullOrEmpty(score))) { // Prepare DB query QueryDataParameters parameters = new QueryDataParameters(); parameters.Add("@ContactID", ci.ContactID); parameters.Add("@ScoreName", score); parameters.Add("@SiteID", siteId); string where = "(Expiration IS NULL OR Expiration > GetDate()) AND (ContactID=@ContactID) AND (ScoreName=@ScoreName) AND (ScoreSiteID=@SiteID)"; // Get sum of points of the contact in specified score DataSet ds = SqlHelperClass.ExecuteQuery("om.score.selectdatajoined", parameters, "SUM(Value) AS Score", where, null, -1); if (!DataHelper.DataSourceIsEmpty(ds)) { return ValidationHelper.GetInteger(ds.Tables[0].Rows[0][0], 0); } } return 0; } /// /// Returns e-mail domain name. /// /// E-mail address public static string GetEmailDomain(object email) { return ContactHelper.GetEmailDomain(ValidationHelper.GetString(email, string.Empty)); } /// /// Returns true if contact belongs to specified account. /// /// Contact info object /// Account ID public static bool BelongsToAccount(object contact, object accountID) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } int accId = ValidationHelper.GetInteger(accountID, 0); if (accId > 0) { return AccountContactInfoProvider.GetAccountContactInfo(accId, ci.ContactID) != null; } return false; } /// /// Returns true if the contact did any/all of the specified activities. /// /// Contact the activities of which should be checked /// Name of the activity(ies) to check separated with semicolon /// Constraint for last X days (if zero or negative value is given, no constraint is applied) /// If true, all specified types has to be found for the method to return true. If false, at least one of any specified types is sufficient to return true for the method. public static bool DidActivities(object contact, string activityTypes, int lastXDays, bool allActivities) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } string where = null; string[] activities = activityTypes.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string activityType in activities) { where = SqlHelperClass.AddWhereCondition(where, "ActivityType = N'" + SqlHelperClass.GetSafeQueryString(activityType, false) + "'", "OR"); } if (lastXDays > 0) { where = SqlHelperClass.AddWhereCondition(where, "DATEADD(day, " + lastXDays + ", ActivityCreated) >= GETDATE()"); } where = SqlHelperClass.AddWhereCondition(where, "ActivityActiveContactID = " + ci.ContactID); DataSet ds = ActivityInfoProvider.GetActivities(where, null, 0, "DISTINCT ActivityType"); if (!DataHelper.DataSourceIsEmpty(ds)) { if (allActivities) { return ds.Tables[0].Rows.Count == activities.Length; } else { return true; } } return false; } /// /// Returns true if the contact did a specified activity. /// /// Contact the activities of which should be checked /// Name of the activity to check (can specify more than one separated with semicolon, all of the types match than) /// Name of the activity which cancels the original activity (for example UnsubscribeNewsletter is a cancelling event for SubscribeNewsletter etc.) /// Constraint for last X days (if zero or negative value is given, no constraint is applied) /// Additional WHERE condition public static bool DidActivity(object contact, string activityType, string cancelActivityType, int lastXDays, string whereCondition) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } string where = GetActivityWhere(activityType, cancelActivityType, lastXDays, whereCondition, ci.ContactID); DataSet ds = ActivityInfoProvider.GetActivities(where, null, 1, "ActivityID"); if (!DataHelper.DataSourceIsEmpty(ds)) { return true; } return false; } private static string GetActivityWhere(string activityType, string cancelActivityType, int lastXDays, string whereCondition, int contactId) { string where = "ActivityActiveContactID = " + contactId; if (!string.IsNullOrEmpty(activityType)) { string[] types = activityType.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); string typeWhere = null; foreach (string type in types) { typeWhere = SqlHelperClass.AddWhereCondition(typeWhere, "ActivityType = N'" + SqlHelperClass.GetSafeQueryString(type, false) + "'", "OR"); } where = SqlHelperClass.AddWhereCondition(where, typeWhere); } if (!string.IsNullOrEmpty(cancelActivityType)) { // Exclude activities which has been cancelled by its counter activity (subscribe vs. unsubscribe) where = SqlHelperClass.AddWhereCondition(where, "NOT EXISTS(SELECT ActivityID FROM OM_Activity AS A2 WHERE A2.ActivityType = N'" + SqlHelperClass.GetSafeQueryString(cancelActivityType, false) + "' AND OM_Activity.ActivityItemID = A2.ActivityItemID AND A2.ActivityCreated > OM_Activity.ActivityCreated AND OM_Activity.ActivityActiveContactID = A2.ActivityActiveContactID)"); } if (lastXDays > 0) { where = SqlHelperClass.AddWhereCondition(where, "DATEADD(day, " + lastXDays + ", ActivityCreated) >= GETDATE()"); } if (!string.IsNullOrEmpty(whereCondition)) { where = SqlHelperClass.AddWhereCondition(where, whereCondition); } return where; } /// /// Returns true if the contact's country matches one of the specified countries. /// /// Contact the activities of which should be checked /// Countries list (separated with semicolon) public static bool IsFromCountry(object contact, string countryList) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } CountryInfo country = CountryInfoProvider.GetCountryInfo(ci.ContactCountryID); if (country == null) { return false; } string[] countries = countryList.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string c in countries) { if (c.EqualsCSafe(country.CountryDisplayName, true) || c.EqualsCSafe(country.CountryName, true)) { return true; } } return false; } /// /// Returns true if the contact's country matches one of the specified countries. /// /// Contact the activities of which should be checked /// State list (separated with semicolon) public static bool IsFromState(object contact, string stateList) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } StateInfo state = StateInfoProvider.GetStateInfo(ci.ContactStateID); if (state == null) { return false; } string[] states = stateList.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string s in states) { if (s.EqualsCSafe(state.StateDisplayName, true) || s.EqualsCSafe(state.StateName, true)) { return true; } } return false; } /// /// Returns true if the contact did search (internal or external) for specified keywords in last X days. /// /// Contact the activities of which should be checked /// Constraint for last X days (if zero or negative value is given, no constraint is applied) /// Keywords separated with comma or semicolon (if null or empty, than method returns true iff contact did any search in last X days) /// If true all keywords has to be matched, if false at least one match has to be found public static bool SearchedForKeywords(object contact, string keywords, int lastXDays, bool allKeywords) { // Make sure correct operator is passed string op = null; if (allKeywords) { op = "AND"; } else { op = "OR"; } string where = null; string[] words = keywords.Split(new char[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); if (words.Length > 0) { string innerWhere = null; foreach (string item in words) { innerWhere = SqlHelperClass.AddWhereCondition(innerWhere, "SearchKeywords LIKE N'%" + SqlHelperClass.GetSafeQueryString(item) + "%'", op); } where = SqlHelperClass.AddWhereCondition(where, "ActivityID IN (SELECT SearchActivityID FROM OM_Search WHERE " + innerWhere + ")"); } if (!string.IsNullOrEmpty(keywords)) { where = SqlHelperClass.AddWhereCondition(where, "ActivityID IN (SELECT SearchActivityID FROM OM_Search WHERE SearchKeywords = N'" + SqlHelperClass.GetSafeQueryString(keywords, false) + "')", "OR"); } return DidActivity(contact, PredefinedActivityType.INTERNAL_SEARCH + ";" + PredefinedActivityType.EXTERNAL_SEARCH, null, lastXDays, where); } /// /// Returns true if the contact spent specified amount of money (counted by order total price in main currency) in last X days. /// /// Contact the activities of which should be checked /// Inclusive lower bound of the amount of money (in main currency) spent by contact /// Inclusive upper bound of the amount of money (in main currency) spent by contact /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool SpentMoney(object contact, double lowerBound, double upperBound, int lastXDays) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } string where = String.Format("ActivityType = '{0}' AND ActivityActiveContactID = {1}", PredefinedActivityType.PURCHASE, ci.ContactID); if (lastXDays > 0) { where = SqlHelperClass.AddWhereCondition(where, "DATEADD(day, " + lastXDays + ", ActivityCreated) >= GETDATE()"); } DataSet ds = ActivityInfoProvider.GetActivities(where, null, 1, "SUM(CAST(ActivityValue AS FLOAT))"); if (!DataHelper.DataSourceIsEmpty(ds)) { double amount = ValidationHelper.GetDouble(ds.Tables[0].Rows[0][0], -1); if ((amount > -1) && (amount >= lowerBound) && (amount <= upperBound)) { return true; } } return false; } /// /// Returns true if the contact purchased specified number of products in last X days. /// /// Contact the activities of which should be checked /// Inclusive lower bound of the number of products bought /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool PurchasedNumberOfProducts(object contact, int lowerBound, int lastXDays) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } string where = String.Format("ActivityType = '{0}' AND ActivityActiveContactID = {1}", PredefinedActivityType.PURCHASEDPRODUCT, ci.ContactID); if (lastXDays > 0) { where = SqlHelperClass.AddWhereCondition(where, "DATEADD(day, " + lastXDays + ", ActivityCreated) >= GETDATE()"); } DataSet ds = ActivityInfoProvider.GetActivities(where, null, 1, "COUNT(ActivityID)"); if (!DataHelper.DataSourceIsEmpty(ds)) { int amount = ValidationHelper.GetInteger(ds.Tables[0].Rows[0][0], -1); if ((amount > -1) && (amount >= lowerBound)) { return true; } } return false; } /// /// Returns true if the contact is in any/all of the specified roles (i.e. if any of the user assigned to the contact is in any/all specified roles). /// /// Contact which should be checked /// Name of the roles separated with semicolon /// If true, contact has to in all specified roles. If false, it is sufficient if the contact is at least in one of the roles. public static bool IsInRoles(object contact, string roleNames, bool allRoles) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } if (!string.IsNullOrEmpty(roleNames)) { string[] roles = roleNames.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string roleName in roles) { bool isInRole = false; foreach (UserInfo user in ci.Users) { isInRole = user.IsInRole(roleName, CMSContext.CurrentSiteName, true, true); if (isInRole && !allRoles) { // In role and it is sufficient if at least one matches => true return true; } } if (!isInRole && allRoles) { // Not in role, but should be in all roles return false; } } } if (allRoles) { // It means either no roles were specified or contact is in all roles return true; } else { return false; } } /// /// Returns true if the contact is in any/all of the specified community groups (i.e. if any of the user assigned to the contact is in any/all specified community groups). /// /// Contact which should be checked /// Name of the groups separated with semicolon /// If true, contact has to in all specified groups. If false, it is sufficient if the contact is at least in one of the groups. public static bool IsInCommunityGroup(object contact, string groupNames, bool allGroups) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } if (!string.IsNullOrEmpty(groupNames)) { string[] groups = groupNames.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string groupName in groups) { bool isInGroup = false; foreach (UserInfo user in ci.Users) { BaseInfo group = ModuleCommands.CommunityGetGroupInfoByName(groupName, CMSContext.CurrentSiteName); if (group != null) { isInGroup = ModuleCommands.CommunityIsMemberOfGroup(user.UserID, group.Generalized.ObjectID); if (isInGroup && !allGroups) { // In role and it is sufficient if at least one matches => true return true; } } } if (!isInGroup && allGroups) { // Not in role, but should be in all roles return false; } } } if (allGroups) { // It means either no roles were specified or contact is in all roles return true; } else { return false; } } /// /// Returns true if the contact submitted specified form. /// /// Contact which should be checked /// Form name /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool SubmittedForm(object contact, string formName, int lastXDays) { int formId = ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(PredefinedObjectType.BIZFORM, formName, CMSContext.CurrentSiteName, true), 0); return DidActivity(contact, PredefinedActivityType.BIZFORM_SUBMIT, null, lastXDays, "ActivityItemID = " + formId); } /// /// Returns true if the contact opened specified newsletter. /// /// Contact which should be checked /// Newsletter name /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool OpenedNewsletter(object contact, string newsletterName, int lastXDays) { int newsletterId = ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(PredefinedObjectType.NEWSLETTER, newsletterName, CMSContext.CurrentSiteName), 0); return DidActivity(contact, PredefinedActivityType.NEWSLETTER_OPEN, null, lastXDays, "ActivityItemID = " + newsletterId); } /// /// Returns true if the contact voted in the poll. /// /// Contact which should be checked /// Poll name /// Poll answer text /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool VotedInPoll(object contact, string pollName, string answer, int lastXDays) { int pollId = ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(PredefinedObjectType.POLL, pollName, CMSContext.CurrentSiteName, true), 0); if (!string.IsNullOrEmpty(answer)) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } string where = GetActivityWhere(PredefinedActivityType.POLL_VOTING, null, lastXDays, "ActivityItemID = " + pollId, ci.ContactID); DataSet ds = ActivityInfoProvider.GetActivities(where, null, 0, "ActivityValue"); if (!DataHelper.DataSourceIsEmpty(ds)) { foreach (DataRow dr in ds.Tables[0].Rows) { string[] answers = ValidationHelper.GetString(dr[0], "").Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); foreach (string a in answers) { BaseInfo pollAnswer = CMSObjectHelper.GetObjectById("polls.pollanswer", ValidationHelper.GetInteger(a, 0)); if (pollAnswer != null) { if (pollAnswer.GetStringValue("AnswerText", "").EqualsCSafe(answer, true)) { return true; } } } } } return false; } else { return DidActivity(contact, PredefinedActivityType.POLL_VOTING, null, lastXDays, "ActivityItemID = " + pollId); } } /// /// Returns true if the contact logged in. /// /// Contact which should be checked /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool LoggedIn(object contact, int lastXDays) { return DidActivity(contact, PredefinedActivityType.USER_LOGIN, null, lastXDays, null); } /// /// Checks whether contact is subscribed to the given newsletter. Check is made based on the contact's email address. If /// there is a subscriber with the contact's email subscribed to the newsletter, it means contact is subscribed. /// /// Contact whose email should be checked /// Newsletter name /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool SubscribedToNewsletter(object contact, string newsletterName, int lastXDays) { ContactInfo contactInfo = contact as ContactInfo; if ((contactInfo == null) || string.IsNullOrEmpty(contactInfo.ContactEmail)) { return false; } int currentSiteId = CMSContext.CurrentSiteID; var newsletter = NewsletterInfoProvider.GetNewsletterInfo(newsletterName, currentSiteId); if (newsletter == null) { return false; } bool? subscriberWithEmailIsSubscribed = SubscriberWithEmailIsSubscribed(contactInfo.ContactEmail, newsletter.NewsletterID, lastXDays); // Check activities if subscribed with the contact's email was not found if (subscriberWithEmailIsSubscribed == null) { return DidActivity(contactInfo, PredefinedActivityType.NEWSLETTER_SUBSCRIBING, PredefinedActivityType.NEWSLETTER_UNSUBSCRIBING, lastXDays, "ActivityItemID = " + newsletter.NewsletterID); } return subscriberWithEmailIsSubscribed.Value; } /// /// Checks if there is a subscriber with the given email subscribed to the newsletter. /// /// Email of the subscriber /// Newsletter ID /// Number of days before now where subscription is considered valid. If 0, check based on date is not made. /// /// True - subscribed is subscribed and is active /// False - subscribed is subscribed, but his subscription is cancelled /// Null - subscription with this email was not found and check based on the activities should be made /// private static bool? SubscriberWithEmailIsSubscribed(string subscriberEmail, int newsletterId, int lastXDays) { var subscriber = SubscriberInfoProvider.GetSubscriberByEmail(subscriberEmail, CMSContext.CurrentSiteID); if (subscriber == null) { return null; } var subscription = SubscriberNewsletterInfoProvider.GetSubscriberNewsletterInfo(subscriber.SubscriberID, newsletterId); if (subscription == null) { return null; } if (!subscription.SubscriptionEnabled || !subscription.SubscriptionApproved) { return false; } if (lastXDays > 0 && subscription.SubscribedWhen < DateTime.Now.AddDays(-lastXDays)) { return false; } return true; } /// /// Returns true if the contact clicked link in specified newsletter. /// /// Contact which should be checked /// Newsletter name /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool ClickedLinkInNewsletter(object contact, string newsletterName, int lastXDays) { int newsletterId = ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(PredefinedObjectType.NEWSLETTER, newsletterName, CMSContext.CurrentSiteName, true), 0); return DidActivity(contact, PredefinedActivityType.NEWSLETTER_CLICKTHROUGH, null, lastXDays, "ActivityItemID = " + newsletterId); } /// /// Returns true if the contact clicked link in the specified newsletter issue. /// /// Contact that should be checked /// Newsletter issue GUID /// Indicates whether contact should have clicked the newsletter issue or just open it. /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool InteractedWithNewsletterIssue(object contact, Guid issueGuid, bool click, int lastXDays) { ContactInfo ci = contact as ContactInfo; if (ci != null) { IssueInfo issue = IssueInfoProvider.GetIssueInfo(issueGuid, ci.ContactSiteID); if (issue != null) { string where = String.Format("ActivityItemID = {0} AND ActivityItemDetailID = {1}", issue.IssueNewsletterID, issue.IssueID); return DidActivity(contact, click ? PredefinedActivityType.NEWSLETTER_CLICKTHROUGH : PredefinedActivityType.NEWSLETTER_OPEN, null, lastXDays, where); } } return false; } /// /// Returns true if the contact purchased specified product. /// /// Contact which should be checked /// Name of the product /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool PurchasedProduct(object contact, string skuName, int lastXDays) { int skuId = ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(PredefinedObjectType.SKU, skuName, CMSContext.CurrentSiteName, true), 0); return DidActivity(contact, PredefinedActivityType.PURCHASEDPRODUCT, null, lastXDays, "ActivityItemID = " + skuId); } /// /// Returns true if the contact visited specified page. /// /// Contact which should be checked /// Page node alias path /// Culture of the document /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool VisitedPage(object contact, string nodeAliasPath, string culture, int lastXDays) { ContactInfo ci = contact as ContactInfo; if (ci == null) { return false; } if (ci.ContactSiteID == 0) { return false; } TreeProvider tree = new TreeProvider(CMSContext.CurrentUser); TreeNode node = tree.SelectSingleNode(SiteInfoProvider.GetSiteName(ci.ContactSiteID), nodeAliasPath, CMSContext.PreferredCultureCode); if (node != null) { if (string.IsNullOrEmpty(culture)) { return DidActivity(contact, PredefinedActivityType.PAGE_VISIT, null, lastXDays, "ActivityNodeID = " + node.NodeID); } else { return DidActivity(contact, PredefinedActivityType.PAGE_VISIT, null, lastXDays, "ActivityNodeID = " + node.NodeID + " AND ActivityCulture = '" + culture + "'"); } } return false; } /// /// Returns true if the contact registered for specific event. /// /// Contact which should be checked /// Node alias path of BookingEvent document /// Constraint for last X days (if zero or negative value is given, no constraint is applied) public static bool RegisteredForEvent(object contact, string nodeAliasPath, int lastXDays) { return DidActivity(contact, PredefinedActivityType.EVENT_BOOKING, null, lastXDays, "ActivityItemDetailID IN (SELECT DocumentID FROM CMS_Document WHERE DocumentNodeID IN (SELECT NodeID FROM CMS_Tree WHERE NodeAliasPath = N'" + SqlHelperClass.GetSafeQueryString(nodeAliasPath, false) + "'))"); } /// /// Returns last newsletter issue that was sent to the contact of the state. /// /// Automation state public static IssueInfo GetLastNewsletterIssue(AutomationStateInfo state) { // Check if automation state is null if (state == null) { return null; } // Get newsletter issue GUID var newsletterGuid = ValidationHelper.GetGuid(state.StateCustomData[SendNewsletterIssueAction.LAST_SENT_NEWSLETTER_ISSUE_KEY], Guid.Empty); if (newsletterGuid == Guid.Empty) { return null; } return IssueInfoProvider.GetIssueInfo(newsletterGuid, state.StateSiteID); } /// /// Returns if activity is linked to object of type given in parameter and codename given in second parameter. /// /// Activity that should be checked /// Object type /// Code name or GUID of object public static bool ActivityLinkedToObject(ActivityInfo activityInfo, string objectType, string identifier) { if (activityInfo == null) { return false; } int id = 0; switch (objectType) { case PredefinedObjectType.POLL: case PredefinedObjectType.NEWSLETTER: case PredefinedObjectType.BIZFORM: case PredefinedObjectType.FORUM: case PredefinedObjectType.GROUPMEMBER: case PredefinedObjectType.BOARDMESSAGE: case PredefinedObjectType.BOARD: case PredefinedObjectType.SKU: id = activityInfo.ActivityItemID; break; case PredefinedObjectType.NEWSLETTERISSUE: var issue = IssueInfoProvider.GetOriginalIssue(activityInfo.ActivityItemDetailID); if (issue != null) { id = issue.IssueID; } break; case PredefinedObjectType.BLOGDOCUMENT: id = activityInfo.ActivityItemDetailID; objectType = PredefinedObjectType.NODE; break; case PredefinedObjectType.DOCUMENT: case PredefinedObjectType.NODE: id = activityInfo.ActivityNodeID; break; default: id = activityInfo.ActivityItemID; break; } return (id == ValidationHelper.GetInteger(CMSMacroMethods.GetObjectID(objectType, identifier, CMSContext.CurrentSiteName, true), -1)); } }