/// <summary> /// Finds any missing personal link section orders /// and <see cref="Rock.Data.Service{T}.Add(T)">adds</see> them (but doesn't .SaveChanges) /// If this returns true, call SaveChanges to save them to the database. /// </summary> /// <param name="currentPerson">The current person.</param> /// <returns>List<PersonalLinkSectionOrder>.</returns> public bool AddMissingPersonalLinkSectionOrders(Person currentPerson) { var primaryAliasId = currentPerson.PrimaryAliasId; if (!primaryAliasId.HasValue) { // shouldn't happen, but just in case return(false); } var rockContext = this.Context as RockContext; var personalLinkSectionService = new PersonalLinkSectionService(rockContext); var personAliasQuery = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == currentPerson.Id); var personalLinkSectionsQuery = personalLinkSectionService .Queryable() .Where(a => a.IsShared || (a.PersonAliasId.HasValue && personAliasQuery.Any(aa => aa.Id == a.PersonAliasId.Value))); var missingSectionOrders = personalLinkSectionsQuery .Where(a => !a.PersonalLinkSectionOrders.Any(xx => personAliasQuery.Any(pa => pa.Id == xx.PersonAliasId))) .ToList() .OrderBy(a => a.Name) .Select(a => new PersonalLinkSectionOrder { PersonAliasId = primaryAliasId.Value, SectionId = a.Id, Order = 0 }).ToList(); if (missingSectionOrders.Any()) { // add the new order for sections to the bottom of the list for that section (in order by name) var personalLinkSectionOrderService = new PersonalLinkSectionOrderService(rockContext); var lastSectionOrder = personalLinkSectionOrderService.Queryable().Where(a => a.PersonAlias.PersonId == currentPerson.Id).Max(a => ( int? )a.Order) ?? 0; foreach (var missingSectionOrder in missingSectionOrders) { missingSectionOrder.Order = lastSectionOrder++; } personalLinkSectionOrderService.AddRange(missingSectionOrders); return(true); } else { return(false); } }
/// <summary> /// Gets the section order query. /// Use this to make sure to get the best match for in cases where /// a person has more than one sort order for a section (which could happen if there was person merge) /// </summary> /// <remarks> /// If you are unsure if there are some sections that don't have an order, use <see cref="AddMissingPersonalLinkSectionOrders(Person)"/> first. /// </remarks> /// <param name="person">The person.</param> /// <returns>System.Linq.IQueryable<Rock.Model.PersonalLinkSectionOrder>.</returns> public IOrderedQueryable <PersonalLinkSectionOrder> GetSectionOrderQuery(Person person) { var rockContext = this.Context as RockContext; var personAliasQuery = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == person.Id); // There could be duplicate Orders for a Section for a person if the person was merged. // So, to ensure a consistent Order winner, also sort by ModifiedDateTime. That will // ensure the the most recent sort will be one the current person sees. var personalLinkSectionOrder = new PersonalLinkSectionOrderService(rockContext).Queryable() .Where(a => personAliasQuery.Any(xx => xx.Id == a.PersonAliasId)) .GroupBy(a => a.SectionId) .Select(a => a.OrderBy(xx => xx.Order).ThenByDescending(xx => xx.ModifiedDateTime).FirstOrDefault()) .OrderBy(a => a.Order); return(personalLinkSectionOrder); }
/// <summary> /// Gets current login's LastModifiedDateTime <see cref="Rock.Model.PersonalLink" /> data from <see cref="System.Web.SessionState">Session</see>. /// </summary> /// <remarks> /// We cache PersonalLinksLastUpdateDateTime in session so that we know if the LocalStorage of PersonalLinks needs to be updated. /// </remarks> public static DateTime?GetPersonalLinksLastModifiedDateTime(Person currentPerson) { if (currentPerson == null) { return(null); } DateTime?lastModifiedDateTime = null; if (HttpContext.Current?.Session != null) { // If we already got the LastModifiedDateTime, we'll store it in session so that we don't have to keep asking lastModifiedDateTime = HttpContext.Current.Session[SessionKey.PersonalLinksLastUpdateDateTime] as DateTime?; } else { // If we dont' have a Session, see if we are storing it for the current request; lastModifiedDateTime = HttpContext.Current?.Items[SessionKey.PersonalLinksLastUpdateDateTime] as DateTime?; } if (lastModifiedDateTime.HasValue) { return(lastModifiedDateTime); } // NOTE: Session can be null (probably because it is a REST call). Or maybe it hasn't been set in Session yet So, we'll get it from the Database; var rockContext = new RockContext(); var personAliasQuery = new PersonAliasService(rockContext).Queryable().Where(a => a.PersonId == currentPerson.Id); var sectionLastModifiedDateTimeQuery = new PersonalLinkSectionService(rockContext) .Queryable() .Where(a => !a.IsShared && a.ModifiedDateTime.HasValue && a.PersonAliasId.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId)) .Select(a => a.ModifiedDateTime); var linkLastModifiedDateTimeQuery = new PersonalLinkService(rockContext) .Queryable() .Where(a => a.ModifiedDateTime.HasValue && a.PersonAliasId.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId)) .Select(a => a.ModifiedDateTime); var linkOrderLastModifiedDateTimeQuery = new PersonalLinkSectionOrderService(rockContext) .Queryable() .Where(a => a.ModifiedDateTime.HasValue && personAliasQuery.Any(x => x.Id == a.PersonAliasId)) .Select(a => a.ModifiedDateTime); lastModifiedDateTime = sectionLastModifiedDateTimeQuery.Union(linkLastModifiedDateTimeQuery).Union(linkOrderLastModifiedDateTimeQuery).Max(a => a); if (HttpContext.Current?.Session != null) { if (lastModifiedDateTime == null) { // If LastModifiedDateTime is still null, they don't have any personal links, // So we'll set LastModifiedDateTime to Midnight (so it doesn't keep checking the database) lastModifiedDateTime = RockDateTime.Today; } // If we already got the LastModifiedDateTime, we'll store it in session so that we don't have to keep asking HttpContext.Current.Session[SessionKey.PersonalLinksLastUpdateDateTime] = lastModifiedDateTime; } else { // if we don't have Session, store it in the current request (just in case this called multiple times in the same request) if (HttpContext.Current != null) { HttpContext.Current.Items[SessionKey.PersonalLinksLastUpdateDateTime] = lastModifiedDateTime; } } return(lastModifiedDateTime); }