/// <summary> /// Deletes the threads matching the passed in filter, inside the transaction specified. /// </summary> /// <param name="threadFilter">The thread filter.</param> /// <param name="trans">The transaction to use.</param> private static void DeleteThreads(PredicateExpression threadFilter, Transaction trans) { // we've to perform a set of actions in a given order to make sure we're not violating FK constraints in the DB. // delete messages in thread MessageManager.DeleteAllMessagesInThreads(threadFilter, trans); // delete bookmarks (if exists) of the threads to be deleted BookmarkCollection bookmarks = new BookmarkCollection(); trans.Add(bookmarks); // use again a fieldcompareset predicate bookmarks.DeleteMulti(new FieldCompareSetPredicate(BookmarkFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete audit info related to this thread. Can't be done directly on the db due to the fact the entities are in a TargetPerEntity hierarchy, which // can't be deleted directly on the db, so we've to fetch the entities first. AuditDataThreadRelatedCollection threadAuditData = new AuditDataThreadRelatedCollection(); trans.Add(threadAuditData); // use a fieldcompareset predicate filter, based on the threadFilter. threadAuditData.GetMulti(new FieldCompareSetPredicate(AuditDataThreadRelatedFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); threadAuditData.DeleteMulti(); // delete support queue thread entity for this thread (if any) SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); trans.Add(supportQueueThreads); // use again a fieldcompareset predicate supportQueueThreads.DeleteMulti(new FieldCompareSetPredicate(SupportQueueThreadFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete threadsubscription entities ThreadSubscriptionCollection threadSubscriptions = new ThreadSubscriptionCollection(); trans.Add(threadSubscriptions); // use again a fieldcompareset predicate threadSubscriptions.DeleteMulti(new FieldCompareSetPredicate(ThreadSubscriptionFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete the threads ThreadCollection threads = new ThreadCollection(); trans.Add(threads); // we already have the filter to use, namely the filter passed in. threads.DeleteMulti(threadFilter); // don't commit the transaction, that's up to the caller. }
/// <summary> /// Sends email to all users subscribed to a specified thread, except the user who initiated the thread update. /// </summary> /// <param name="threadID">The thread that was updated.</param> /// <param name="initiatedByUserID">The user who initiated the update (who will not receive notification).</param> private static void SendThreadReplyNotifications(int threadID, int initiatedByUserID, string emailTemplate, Dictionary<string, string> emailData) { // get list of subscribers to thread, minus the initiator. Do this by fetching the subscriptions plus the related user entity entity instances. // The related user entities are loaded using a prefetch path. var qf = new QueryFactory(); var q = qf.ThreadSubscription .Where((ThreadSubscriptionFields.ThreadID == threadID).And(ThreadSubscriptionFields.UserID != initiatedByUserID)) .WithPath(ThreadSubscriptionEntity.PrefetchPathUser); ThreadSubscriptionCollection subscriptions = new ThreadSubscriptionCollection(); subscriptions.GetMulti(q); if(subscriptions.Count <= 0) { // no subscriptions, nothing to do return; } // now collect all email addresses into an array so we can pass that to the email routine. string[] toAddresses = new string[subscriptions.Count]; for(int i=0;i<subscriptions.Count;i++) { toAddresses[i] = subscriptions[i].User.EmailAddress; } // use template to construct message to send. StringBuilder mailBody = new StringBuilder(emailTemplate); string applicationURL = string.Empty; emailData.TryGetValue("applicationURL", out applicationURL); if (!string.IsNullOrEmpty(emailTemplate)) { // Use the existing template to format the body string siteName = string.Empty; emailData.TryGetValue("siteName", out siteName); string threadSubject = string.Empty; string threadUrl = string.Empty; ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); if(thread != null) { threadSubject = thread.Subject; threadUrl = applicationURL + string.Format("Messages.aspx?ThreadID={0}", thread.ThreadID); } else { // thread doesn't exist, exit return; } mailBody.Replace("[SiteURL]", applicationURL); mailBody.Replace("[SiteName]", siteName); mailBody.Replace("[ThreadSubject]", threadSubject); mailBody.Replace("[ThreadURL]", threadUrl); } // format the subject string subject = string.Empty; emailData.TryGetValue("emailThreadNotificationSubject", out subject); subject += applicationURL; string fromAddress = string.Empty; emailData.TryGetValue("defaultFromEmailAddress", out fromAddress); try { //send message HnDGeneralUtils.SendEmail(subject, mailBody.ToString(), fromAddress, toAddresses, emailData, true); } catch(SmtpFailedRecipientsException) { // swallow as it shouldn't have any effect on further operations } catch(SmtpException) { // swallow, as there's nothing we can do } // rest: problematic, so bubble upwards. }
/// <summary> /// Deletes the threads matching the passed in filter, inside the transaction specified. /// </summary> /// <param name="threadFilter">The thread filter.</param> /// <param name="trans">The transaction to use.</param> private static void DeleteThreads(PredicateExpression threadFilter, Transaction trans) { // we've to perform a set of actions in a given order to make sure we're not violating FK constraints in the DB. // delete messages in thread MessageManager.DeleteAllMessagesInThreads(threadFilter, trans); // delete bookmarks (if exists) of the threads to be deleted BookmarkCollection bookmarks = new BookmarkCollection(); trans.Add(bookmarks); // use again a fieldcompareset predicate bookmarks.DeleteMulti(new FieldCompareSetPredicate(BookmarkFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete audit info related to this thread. Can't be done directly on the db due to the fact the entities are in a TargetPerEntity hierarchy, which // can't be deleted directly on the db, so we've to fetch the entities first. AuditDataThreadRelatedCollection threadAuditData = new AuditDataThreadRelatedCollection(); trans.Add(threadAuditData); // use a fieldcompareset predicate filter, based on the threadFilter. threadAuditData.GetMulti(new FieldCompareSetPredicate(AuditDataThreadRelatedFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); threadAuditData.DeleteMulti(); // delete support queue thread entity for this thread (if any) SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); trans.Add(supportQueueThreads); // use again a fieldcompareset predicate supportQueueThreads.DeleteMulti(new FieldCompareSetPredicate(SupportQueueThreadFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete threadsubscription entities ThreadSubscriptionCollection threadSubscriptions = new ThreadSubscriptionCollection(); trans.Add(threadSubscriptions); // use again a fieldcompareset predicate threadSubscriptions.DeleteMulti(new FieldCompareSetPredicate(ThreadSubscriptionFields.ThreadID, ThreadFields.ThreadID, SetOperator.In, threadFilter)); // delete the threads ThreadCollection threads = new ThreadCollection(); trans.Add(threads); // we already have the filter to use, namely the filter passed in. threads.DeleteMulti(threadFilter); // don't commit the transaction, that's up to the caller. }
/// <summary> /// Deletes the user with the ID passed in. Will reset all posts made by the user to the userid 0. /// </summary> /// <param name="userID">The user ID.</param> /// <remarks>Can't delete user 0</remarks> /// <returns>true if succeeded, false otherwise</returns> public static bool DeleteUser(int userID) { if(userID == 0) { // can't delete the Anonymous coward user. return false; } UserEntity toDelete = UserGuiHelper.GetUser(userID); if(toDelete==null) { // user doesn't exist return false; } // all actions have to take place in a transaction. Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteUser"); try { // we'll first update all PostedByUserId fields of all messages which are posted by the user to delete. MessageEntity messageUpdater = new MessageEntity(); messageUpdater.PostedByUserID = 0; // reset to AC. MessageCollection messages = new MessageCollection(); trans.Add(messages); // add to the transaction // update all entities directly in the DB, which match the following filter and update them with the new values set in messageUpdater. messages.UpdateMulti(messageUpdater, (MessageFields.PostedByUserID == userID)); // set the startuser of threads started by this user to 0 ThreadEntity threadUpdater = new ThreadEntity(); threadUpdater.StartedByUserID = 0; ThreadCollection threads = new ThreadCollection(); trans.Add(threads); threads.UpdateMulti(threadUpdater, (ThreadFields.StartedByUserID == userID)); // remove the user from the UserRoles set, as the user shouldn't be in any roles. RoleUserCollection roleUsersDeleter = new RoleUserCollection(); trans.Add(roleUsersDeleter); // delete all entities directly from the DB which match the following filter. roleUsersDeleter.DeleteMulti(RoleUserFields.UserID == userID); // delete all bookmarks of user BookmarkCollection bookmarkDeleter = new BookmarkCollection(); trans.Add(bookmarkDeleter); // delete all bookmarks for this user directly from the DB using the following filter. bookmarkDeleter.DeleteMulti(BookmarkFields.UserID == userID); // delete all audit data AuditDataCoreCollection auditDataDeleter = new AuditDataCoreCollection(); // first fetch it, then delete all entities from the collection, as the audit data is in an inheritance hierarchy of TargetPerEntity which can't // be deleted directly from the db. trans.Add(auditDataDeleter); auditDataDeleter.GetMulti(AuditDataCoreFields.UserID == userID); auditDataDeleter.DeleteMulti(); // set IP bans set by this user to userid 0 IPBanEntity ipbanUpdater = new IPBanEntity(); ipbanUpdater.IPBanSetByUserID = 0; IPBanCollection ipBans = new IPBanCollection(); trans.Add(ipBans); ipBans.UpdateMulti(ipbanUpdater, (IPBanFields.IPBanSetByUserID == userID)); // delete threadsubscriptions ThreadSubscriptionCollection threadSubscriptionsDeleter = new ThreadSubscriptionCollection(); trans.Add(threadSubscriptionsDeleter); threadSubscriptionsDeleter.DeleteMulti(ThreadSubscriptionFields.UserID == userID); // remove supportqueuethread claims SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); trans.Add(supportQueueThreads); supportQueueThreads.DeleteMulti(SupportQueueThreadFields.ClaimedByUserID == userID); // set all placed in queue references to userid 0, so the threads stay in the queues. SupportQueueThreadEntity supportQueueThreadUpdater = new SupportQueueThreadEntity(); supportQueueThreadUpdater.PlacedInQueueByUserID=0; supportQueueThreads.UpdateMulti(supportQueueThreadUpdater, (SupportQueueThreadFields.PlacedInQueueByUserID == userID)); // now delete the actual user entity trans.Add(toDelete); toDelete.Delete(); // all done trans.Commit(); return true; } catch { trans.Rollback(); throw; } finally { trans.Dispose(); } }
/// <summary> /// Sends email to all users subscribed to a specified thread, except the user who initiated the thread update. /// </summary> /// <param name="threadID">The thread that was updated.</param> /// <param name="initiatedByUserID">The user who initiated the update (who will not receive notification).</param> private static void SendThreadReplyNotifications(int threadID, int initiatedByUserID, string emailTemplate, Dictionary <string, string> emailData) { // get list of subscribers to thread, minus the initiator. Do this by fetching the subscriptions plus the related user entity entity instances. // The related user entities are loaded using a prefetch path. var qf = new QueryFactory(); var q = qf.ThreadSubscription .Where((ThreadSubscriptionFields.ThreadID == threadID).And(ThreadSubscriptionFields.UserID != initiatedByUserID)) .WithPath(ThreadSubscriptionEntity.PrefetchPathUser); ThreadSubscriptionCollection subscriptions = new ThreadSubscriptionCollection(); subscriptions.GetMulti(q); if (subscriptions.Count <= 0) { // no subscriptions, nothing to do return; } // now collect all email addresses into an array so we can pass that to the email routine. string[] toAddresses = new string[subscriptions.Count]; for (int i = 0; i < subscriptions.Count; i++) { toAddresses[i] = subscriptions[i].User.EmailAddress; } // use template to construct message to send. StringBuilder mailBody = new StringBuilder(emailTemplate); string applicationURL = string.Empty; emailData.TryGetValue("applicationURL", out applicationURL); if (!string.IsNullOrEmpty(emailTemplate)) { // Use the existing template to format the body string siteName = string.Empty; emailData.TryGetValue("siteName", out siteName); string threadSubject = string.Empty; string threadUrl = string.Empty; ThreadEntity thread = ThreadGuiHelper.GetThread(threadID); if (thread != null) { threadSubject = thread.Subject; threadUrl = applicationURL + string.Format("Messages.aspx?ThreadID={0}", thread.ThreadID); } else { // thread doesn't exist, exit return; } mailBody.Replace("[SiteURL]", applicationURL); mailBody.Replace("[SiteName]", siteName); mailBody.Replace("[ThreadSubject]", threadSubject); mailBody.Replace("[ThreadURL]", threadUrl); } // format the subject string subject = string.Empty; emailData.TryGetValue("emailThreadNotificationSubject", out subject); subject += applicationURL; string fromAddress = string.Empty; emailData.TryGetValue("defaultFromEmailAddress", out fromAddress); try { //send message HnDGeneralUtils.SendEmail(subject, mailBody.ToString(), fromAddress, toAddresses, emailData, true); } catch (SmtpFailedRecipientsException) { // swallow as it shouldn't have any effect on further operations } catch (SmtpException) { // swallow, as there's nothing we can do } // rest: problematic, so bubble upwards. }
/// <summary> /// Deletes the user with the ID passed in. Will reset all posts made by the user to the userid 0. /// </summary> /// <param name="userID">The user ID.</param> /// <remarks>Can't delete user 0</remarks> /// <returns>true if succeeded, false otherwise</returns> public static bool DeleteUser(int userID) { if (userID == 0) { // can't delete the Anonymous coward user. return(false); } UserEntity toDelete = UserGuiHelper.GetUser(userID); if (toDelete == null) { // user doesn't exist return(false); } // all actions have to take place in a transaction. Transaction trans = new Transaction(IsolationLevel.ReadCommitted, "DeleteUser"); try { // we'll first update all PostedByUserId fields of all messages which are posted by the user to delete. MessageEntity messageUpdater = new MessageEntity(); messageUpdater.PostedByUserID = 0; // reset to AC. MessageCollection messages = new MessageCollection(); trans.Add(messages); // add to the transaction // update all entities directly in the DB, which match the following filter and update them with the new values set in messageUpdater. messages.UpdateMulti(messageUpdater, (MessageFields.PostedByUserID == userID)); // set the startuser of threads started by this user to 0 ThreadEntity threadUpdater = new ThreadEntity(); threadUpdater.StartedByUserID = 0; ThreadCollection threads = new ThreadCollection(); trans.Add(threads); threads.UpdateMulti(threadUpdater, (ThreadFields.StartedByUserID == userID)); // remove the user from the UserRoles set, as the user shouldn't be in any roles. RoleUserCollection roleUsersDeleter = new RoleUserCollection(); trans.Add(roleUsersDeleter); // delete all entities directly from the DB which match the following filter. roleUsersDeleter.DeleteMulti(RoleUserFields.UserID == userID); // delete all bookmarks of user BookmarkCollection bookmarkDeleter = new BookmarkCollection(); trans.Add(bookmarkDeleter); // delete all bookmarks for this user directly from the DB using the following filter. bookmarkDeleter.DeleteMulti(BookmarkFields.UserID == userID); // delete all audit data AuditDataCoreCollection auditDataDeleter = new AuditDataCoreCollection(); // first fetch it, then delete all entities from the collection, as the audit data is in an inheritance hierarchy of TargetPerEntity which can't // be deleted directly from the db. trans.Add(auditDataDeleter); auditDataDeleter.GetMulti(AuditDataCoreFields.UserID == userID); auditDataDeleter.DeleteMulti(); // set IP bans set by this user to userid 0 IPBanEntity ipbanUpdater = new IPBanEntity(); ipbanUpdater.IPBanSetByUserID = 0; IPBanCollection ipBans = new IPBanCollection(); trans.Add(ipBans); ipBans.UpdateMulti(ipbanUpdater, (IPBanFields.IPBanSetByUserID == userID)); // delete threadsubscriptions ThreadSubscriptionCollection threadSubscriptionsDeleter = new ThreadSubscriptionCollection(); trans.Add(threadSubscriptionsDeleter); threadSubscriptionsDeleter.DeleteMulti(ThreadSubscriptionFields.UserID == userID); // remove supportqueuethread claims SupportQueueThreadCollection supportQueueThreads = new SupportQueueThreadCollection(); trans.Add(supportQueueThreads); supportQueueThreads.DeleteMulti(SupportQueueThreadFields.ClaimedByUserID == userID); // set all placed in queue references to userid 0, so the threads stay in the queues. SupportQueueThreadEntity supportQueueThreadUpdater = new SupportQueueThreadEntity(); supportQueueThreadUpdater.PlacedInQueueByUserID = 0; supportQueueThreads.UpdateMulti(supportQueueThreadUpdater, (SupportQueueThreadFields.PlacedInQueueByUserID == userID)); // now delete the actual user entity trans.Add(toDelete); toDelete.Delete(); // all done trans.Commit(); return(true); } catch { trans.Rollback(); throw; } finally { trans.Dispose(); } }