Example #1
0
        /// <summary>
        /// Method that will be called on an entity immediately after the item is saved by context
        /// </summary>
        /// <param name="dbContext">The database context.</param>
        /// <param name="entry">The entry.</param>
        /// <param name="state">The state.</param>
        public override void PreSaveChanges(Data.DbContext dbContext, DbEntityEntry entry, EntityState state)
        {
            if (state == EntityState.Added)
            {
                var noteType = NoteTypeCache.Get(this.NoteTypeId);
                if (noteType?.AutoWatchAuthors == true)
                {
                    // if this is a new note, and AutoWatchAuthors, then add a NoteWatch so the author will get notified when there are any replies
                    var rockContext = dbContext as RockContext;
                    if (rockContext != null && this.CreatedByPersonAliasId.HasValue)
                    {
                        var noteWatchService = new NoteWatchService(rockContext);

                        // we don't know the Note.Id yet, so just assign the NoteWatch.Note and EF will populate the NoteWatch.NoteId automatically
                        var noteWatch = new NoteWatch
                        {
                            IsWatching           = true,
                            WatcherPersonAliasId = this.CreatedByPersonAliasId.Value,
                            Note = this
                        };

                        noteWatchService.Add(noteWatch);
                    }
                }
            }

            base.PreSaveChanges(dbContext, entry, state);
        }
Example #2
0
        /// <summary>
        /// Updates the note watch notification digest.
        /// </summary>
        /// <param name="personIdNotificationDigestList">The person identifier notification digest list.</param>
        /// <param name="rockContext">The rock context.</param>
        /// <param name="noteId">The note identifier.</param>
        private void UpdateNoteWatchNotificationDigest(Dictionary <int, NoteWatchPersonToNotifyList> personIdNotificationDigestList, RockContext rockContext, int noteId)
        {
            var noteService = new Rock.Model.NoteService(rockContext);

            var note = noteService.Queryable().Include(a => a.EditedByPersonAlias).FirstOrDefault(a => a.Id == noteId);

            if (note == null || !note.EntityId.HasValue)
            {
                // shouldn't' happen
                return;
            }

            var noteType = NoteTypeCache.Get(note.NoteTypeId);

            // make sure the note's notetype has an EntityTypeId (is should, but just in case it doesn't)
            int?noteEntityTypeId = noteType?.EntityTypeId;

            if (!noteEntityTypeId.HasValue)
            {
                return;
            }

            var noteWatchService = new Rock.Model.NoteWatchService(rockContext);

            // narrow it down to NoteWatches for the same EntityType as the Note
            var noteWatchesQuery = noteWatchService.Queryable()
                                   .Where(a =>
                                          (a.EntityTypeId.HasValue && a.EntityTypeId.Value == noteEntityTypeId.Value) ||
                                          (a.NoteTypeId.HasValue && a.NoteType.EntityTypeId == noteEntityTypeId));

            // narrow it down to either note watches on..
            // 1) specific Entity
            // 2) specific Note
            // 3) any note of the NoteType
            // 4) any note on the EntityType

            // specific Entity
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.EntityId == null) ||
                                                      (note.EntityId.HasValue && a.EntityId.Value == note.EntityId.Value));

            // or specifically for this Note's ParentNote (a reply to the Note)
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.NoteId == null) ||
                                                      (note.ParentNoteId.HasValue && a.NoteId.Value == note.ParentNoteId));

            // or specifically for this note's note type
            noteWatchesQuery = noteWatchesQuery.Where(a =>
                                                      (a.NoteTypeId == null) ||
                                                      (a.NoteTypeId.Value == note.NoteTypeId));

            // if there are any NoteWatches that relate to this note, process them
            if (noteWatchesQuery.Any())
            {
                var noteWatchesForNote = noteWatchesQuery.Include(a => a.WatcherPersonAlias.Person).AsNoTracking().ToList();
                List <NoteWatchPersonToNotify> noteWatchPersonToNotifyListAll = new List <NoteWatchPersonToNotify>();

                // loop thru Watches to get a list of people to possibly notify/override
                foreach (var noteWatch in noteWatchesForNote)
                {
                    // if a specific person is the watcher, add them
                    var watcherPerson = noteWatch.WatcherPersonAlias?.Person;
                    if (watcherPerson != null)
                    {   // Since this is iterated do not add the person to the list if they are already there.
                        var exists = noteWatchPersonToNotifyListAll.Where(p => p.Person.Email.Contains(watcherPerson.Email)).Any();
                        if (!exists)
                        {
                            noteWatchPersonToNotifyListAll.Add(new NoteWatchPersonToNotify(watcherPerson, note, noteWatch));
                        }
                    }

                    if (noteWatch.WatcherGroupId.HasValue)
                    {
                        var watcherPersonsFromGroup = new GroupMemberService(rockContext).Queryable()
                                                      .Where(a => a.GroupMemberStatus == GroupMemberStatus.Active && a.GroupId == noteWatch.WatcherGroupId.Value)
                                                      .Select(a => a.Person).ToList();

                        if (watcherPersonsFromGroup.Any())
                        {
                            // Do not add people from the group that are already added.
                            var distinctWatchers = watcherPersonsFromGroup.Where(wg => !noteWatchPersonToNotifyListAll.Where(w => w.Person.Email.Contains(wg.Email)).Any());
                            noteWatchPersonToNotifyListAll.AddRange(distinctWatchers.Select(a => new NoteWatchPersonToNotify(a, note, noteWatch)));
                        }
                    }
                }

                var noteWatchPersonToNotifyList = noteWatchPersonToNotifyListAll.Where(a => a.NoteWatch.IsWatching).ToList();
                var noteWatchPersonToNotifyListWatchDisabled = noteWatchPersonToNotifyListAll.Where(a => !a.NoteWatch.IsWatching).ToList();
                var noteWatchPersonToNotifyListNoOverride    = noteWatchPersonToNotifyList.Where(a => a.NoteWatch.AllowOverride == false).ToList();

                foreach (var noteWatchPersonToNotify in noteWatchPersonToNotifyList)
                {
                    // check if somebody wanted to specifically NOT watch this (and there isn't another watch that prevents overrides)
                    if (noteWatchPersonToNotifyListWatchDisabled.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id))
                    {
                        // Person Requested to NOT watch, now make sure that they aren't force to watch based on Override = False
                        if (!noteWatchPersonToNotifyListNoOverride.Any(a => a.Person.Id == noteWatchPersonToNotify.Person.Id))
                        {
                            // person requested to NOT watch, and there aren't any overrides to prevent that, so jump out to the next one
                            continue;
                        }
                    }

                    NoteWatchPersonToNotifyList personToNotifyList;
                    if (personIdNotificationDigestList.ContainsKey(noteWatchPersonToNotify.Person.Id))
                    {
                        // This just create a place holder for the Note referring to item in the digest by key of person
                        personToNotifyList = personIdNotificationDigestList[noteWatchPersonToNotify.Person.Id] ?? new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person);
                    }
                    else
                    {
                        // This just creates  a new place holder for the Note in the digest
                        personToNotifyList = new NoteWatchPersonToNotifyList(noteWatchPersonToNotify.Person);
                        personIdNotificationDigestList.Add(noteWatchPersonToNotify.Person.Id, personToNotifyList);
                    }

                    // Only include the note if the watcher person is authorized to view the note
                    if (noteWatchPersonToNotify.Note.IsAuthorized(Rock.Security.Authorization.VIEW, noteWatchPersonToNotify.Person))
                    {
                        // This is where the get added to the item of the digest
                        personToNotifyList.Add(noteWatchPersonToNotify);
                    }
                }
            }
        }
Example #3
0
        /// <summary>
        /// Returns all Non-Overridable NoteWatches that would prevent this NoteWatch from enabling IsWatching=False
        /// Returns a Queryable of zero or more NoteWatches
        /// </summary>
        /// <param name="rockContext">The rock context.</param>
        /// <returns>
        ///   <c>true</c> if [is allowed to unwatch]; otherwise, <c>false</c>.
        /// </returns>
        public IQueryable <NoteWatch> GetNonOverridableNoteWatches(RockContext rockContext)
        {
            var noteWatchService = new NoteWatchService(rockContext);

            // we are only concerned about other IsWatching watches that don't allow overrides
            var noteWatchesWithOverrideNotAllowedQuery = noteWatchService.Queryable().Where(a => a.AllowOverride == false && a.IsWatching && a.Id != this.Id);

            // limit to notewatches for the same watcher person (or where the watcher person is part of the watcher group)
            if (this.WatcherPersonAliasId.HasValue)
            {
                var watcherPerson = this.WatcherPersonAlias?.Person ?? new PersonAliasService(rockContext).Get(this.WatcherPersonAliasId.Value).Person;

                // limit to watch that are watched by the same person, or watched by a group that a person is an active member of
                noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery
                                                         .Where(a =>
                                                                a.WatcherPersonAliasId.HasValue && a.WatcherPersonAlias.PersonId == this.WatcherPersonAlias.PersonId
                                                                ||
                                                                a.WatcherGroup.Members.Any(gm => gm.GroupMemberStatus == GroupMemberStatus.Active && gm.Person.Aliases.Any(x => x.PersonId == watcherPerson.Id))
                                                                );
            }
            else if (this.WatcherGroupId.HasValue)
            {
                // if the watcher is a Group, make sure it isn't trying to override another watch where the watcher is the same group
                noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a => a.WatcherGroupId.HasValue && a.WatcherGroupId.Value == this.WatcherGroupId.Value);
            }
            else
            {
                // invalid NoteWatch so just return a false query (no records)
                return(noteWatchesWithOverrideNotAllowedQuery.Where(a => false));
            }

            NoteTypeCache noteType = null;

            if (this.NoteTypeId.HasValue)
            {
                noteType = NoteTypeCache.Get(this.NoteTypeId.Value);
            }

            var noteWatchEntityTypeId = this.EntityTypeId ?? noteType?.EntityTypeId;

            //// Find NoteWatches that could override this note watch
            //// We are mostly looking for NoteWatches that are the same or less specific than this watch

            // at a minimum, the EntityType must be the same
            noteWatchesWithOverrideNotAllowedQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a =>
                                                                                                  (a.EntityTypeId.HasValue && a.EntityTypeId.Value == noteWatchEntityTypeId) ||
                                                                                                  (a.NoteTypeId.HasValue && a.NoteType.EntityTypeId == noteWatchEntityTypeId));

            // look for non-overridable notewatches that not specific to a NoteType, NoteId, or Entity,etc
            var globalEntityTypeNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a =>
                                                                                                               a.NoteTypeId == null &&
                                                                                                               a.NoteId == null &&
                                                                                                               a.EntityId == null);

            if (globalEntityTypeNoteWatchesWithNoOverridesQuery.Any())
            {
                // found at least one non-overridable notewatch that covers all notes for the note watch, so it any attempt to unwatch wouldn't block due to the override
                return(globalEntityTypeNoteWatchesWithNoOverridesQuery);
            }

            // if this notewatch is more specific, look for ones that are the same or less specific
            if (this.NoteTypeId.HasValue)
            {
                var noteTypeNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a =>
                                                                                                           (a.NoteTypeId.HasValue && a.NoteTypeId.Value == this.NoteTypeId.Value) &&
                                                                                                           a.NoteId == null &&
                                                                                                           a.EntityId == null);

                if (noteTypeNoteWatchesWithNoOverridesQuery.Any())
                {
                    // found at least one non-overridable notewatch that covers all notes for the note watch and NoteType, so it any attempt to unwatch wouldn't block due to the override
                    return(noteTypeNoteWatchesWithNoOverridesQuery);
                }
            }

            if (this.NoteId.HasValue)
            {
                var noteNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a =>
                                                                                                       (a.NoteId.HasValue && a.NoteId.Value == this.NoteId.Value) &&
                                                                                                       a.EntityId == null);

                if (noteNoteWatchesWithNoOverridesQuery.Any())
                {
                    // found at least one non-overridable notewatch that covers this exact note for the note watch, so it any attempt to unwatch wouldn't block due to the override
                    return(noteNoteWatchesWithNoOverridesQuery);
                }
            }

            if (this.EntityId.HasValue)
            {
                var entityNoteWatchesWithNoOverridesQuery = noteWatchesWithOverrideNotAllowedQuery.Where(a =>
                                                                                                         a.NoteTypeId == null &&
                                                                                                         a.NoteId == null &&
                                                                                                         (a.EntityId.HasValue && (a.EntityId == this.EntityId.Value)));

                if (entityNoteWatchesWithNoOverridesQuery.Any())
                {
                    // found at least one non-overridable notewatch that covers this exact same entity for the note watch, so it any attempt to unwatch wouldn't block due to the override
                    return(entityNoteWatchesWithNoOverridesQuery);
                }
            }

            // no non-overridable conditions found, so return a false query (no records)
            return(noteWatchesWithOverrideNotAllowedQuery.Where(a => false));
        }