/// <summary> /// Generates a random alternate Id search value for use in a /// <see cref="Rock.Model.PersonSearchKey" />. It is comprised of random alpha /// numeric characters in the form ccccccc-ccccccc (7 random characters, a dash, /// and 7 more random characters). Example "f5f3df2-40b8946". /// </summary> /// <param name="verifyUnique">if set to <c>true</c> the key will be verified as unique across all existing "Alternate Id" search values.</param> /// <param name="rockContext">The rock context. You MUST pass in a RockContext if this is going to be called from inside a WrapTransaction save.</param> /// <returns> /// A random key string /// </returns> public static string GenerateRandomAlternateId(bool verifyUnique = true, RockContext rockContext = null) { rockContext = rockContext ?? new RockContext(); string key = string.Empty; if (verifyUnique) { lock ( _obj ) { int alternateValueId = DefinedValueCache.Get(Rock.SystemGuid.DefinedValue.PERSON_SEARCH_KEYS_ALTERNATE_ID.AsGuid()).Id; var service = new PersonSearchKeyService(rockContext); do { key = GenerateRandomAlternateId(); } while (service.Queryable().AsNoTracking().Any(a => a.SearchTypeValueId == alternateValueId && a.SearchValue == key)); } } else { key = GenerateRandomAlternateId(); } return(key); }
/// <summary> /// This method is called in the /// <see cref="M:Rock.Data.Model`1.PreSaveChanges(Rock.Data.DbContext,System.Data.Entity.Infrastructure.DbEntityEntry,System.Data.Entity.EntityState)" /> /// method. Use it to populate <see cref="P:Rock.Data.Model`1.HistoryItems" /> if needed. /// These history items are queued to be written into the database post save (so that they /// are only written if the save actually occurs). /// </summary> /// <param name="dbContext">The database context.</param> /// <param name="entry">The entry.</param> /// <param name="state">The state.</param> protected override void BuildHistoryItems(Data.DbContext dbContext, DbEntityEntry entry, EntityState state) { // Sometimes, especially if the model is being deleted, some properties might not be // populated, but we can query to try to get their original value. We need to use a new // rock context to get the actual value from the DB var rockContext = new RockContext(); var service = new PersonSearchKeyService(rockContext); var originalModel = service.Queryable("PersonAlias") .FirstOrDefault(fpsa => fpsa.Id == Id); // Use the original value for the person alias or the new value if that is not set var personId = (originalModel?.PersonAlias ?? PersonAlias)?.PersonId; if (!personId.HasValue) { // If this model is new, it won't have any virtual properties hydrated or an original // record in the database if (PersonAliasId.HasValue) { var personAliasService = new PersonAliasService(rockContext); var personAlias = personAliasService.Get(PersonAliasId.Value); personId = personAlias?.PersonId; } // We can't log history if we don't know who the saved account belongs to if (!personId.HasValue) { return; } } History.HistoryVerb verb; switch (state) { case EntityState.Added: verb = History.HistoryVerb.Add; break; case EntityState.Deleted: verb = History.HistoryVerb.Delete; break; case EntityState.Modified: verb = History.HistoryVerb.Modify; break; default: // As of now, there is no requirement to log other events return; } var caption = verb == History.HistoryVerb.Modify ? "Person Search Key" : GetCaptionForHistory(originalModel?.SearchValue ?? SearchValue, originalModel?.SearchTypeValueId ?? SearchTypeValueId); var historyChangeList = new History.HistoryChangeList(); if (verb != History.HistoryVerb.Modify) { historyChangeList.AddChange(verb, History.HistoryChangeType.Record, "Person Search Key"); } else { History.EvaluateChange(historyChangeList, $"SearchValue", entry.OriginalValues["SearchValue"].ToStringSafe(), SearchValue, false); var originalSearchType = DefinedValueCache.Get(entry.OriginalValues["SearchTypeValueId"].ToStringSafe().AsInteger()); var currentSearchType = DefinedValueCache.Get(SearchTypeValueId); History.EvaluateChange(historyChangeList, $"SearchType", originalSearchType?.Value, currentSearchType?.Value, false); } HistoryItems = HistoryService.GetChanges( typeof(Person), Rock.SystemGuid.Category.HISTORY_PERSON.AsGuid(), personId.Value, historyChangeList, caption, typeof(PersonSearchKey), Id, dbContext.GetCurrentPersonAlias()?.Id, dbContext.SourceOfChange); }