/// <summary> /// Gets the entity query /// For example: If the EntityTypeId is GroupMember, this will return a GroupMember query of group members that the person is following /// </summary> /// <param name="entityTypeId">The entity type identifier.</param> /// <param name="personId">The person identifier.</param> /// <returns></returns> public IQueryable <IEntity> GetFollowedItems(int entityTypeId, int personId) { EntityTypeCache itemEntityType = EntityTypeCache.Get(entityTypeId); var rockContext = this.Context as RockContext; var followedItemsQry = this.Queryable().Where(a => a.PersonAlias.PersonId == personId && a.EntityTypeId == entityTypeId); if (itemEntityType.AssemblyName != null) { Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); Rock.Data.IService serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { rockContext }) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; entityQry = followedItemsQry.Join( entityQry, f => f.EntityId, e => e.Id, (f, e) => e); return(entityQry); } } return(null); }
/// <summary> /// Gets the entity query for the specified EntityTypeId /// </summary> /// <param name="entityTypeId">The entity type identifier.</param> /// <returns></returns> public IQueryable <IEntity> GetEntityQuery(int entityTypeId) { EntityTypeCache entityTypeCache = EntityTypeCache.Get(entityTypeId); var rockContext = this.Context as RockContext; if (entityTypeCache.AssemblyName != null) { Type entityType = entityTypeCache.GetEntityType(); if (entityType != null) { Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); Rock.Data.IService serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { rockContext }) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; return(entityQry); } } return(null); }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnInit(EventArgs e) { base.OnInit(e); gReport.DataKeyNames = new string[] { "Id" }; gReport.GridRebind += gReport_GridRebind; int tagId = int.MinValue; if (int.TryParse(PageParameter("tagId"), out tagId) && tagId > 0) { Tag _tag = new TagService(new RockContext()).Get(tagId); if (_tag != null) { TagId = tagId; TagEntityType = EntityTypeCache.Read(_tag.EntityTypeId); if (TagEntityType != null) { Type modelType = TagEntityType.GetEntityType(); gReport.RowItemText = modelType.Name + " Tag"; lTaggedTitle.Text = "Tagged " + modelType.Name.Pluralize(); if (modelType != null) { // If displaying people, set the person id fiels so that merge and communication icons are displayed if (TagEntityType.Name == "Rock.Model.Person") { gReport.PersonIdField = "Id"; } foreach (var column in gReport.GetPreviewColumns(modelType)) { gReport.Columns.Add(column); } // Add a CreatedDateTime if one does not exist var gridBoundColumns = gReport.Columns.OfType <BoundField>(); if (gridBoundColumns.Any(c => c.DataField.Equals("CreatedDateTime")) == false) { BoundField addedDateTime = new DateField(); addedDateTime.DataField = "CreatedDateTime"; addedDateTime.SortExpression = "CreatedDateTime"; addedDateTime.HeaderText = "Date Tagged"; gReport.Columns.Add(addedDateTime); } // Add delete column var deleteField = new DeleteField(); gReport.Columns.Add(deleteField); deleteField.Click += gReport_Delete; BindGrid(); } } } } }
/// <summary> /// Returns a queryable collection of <see cref="Rock.Data.IEntity" /> target entities (related to the given source entity) for the given entity type and (optionally) also have a matching purpose key. /// </summary> /// <param name="sourceEntityId">A <see cref="System.Int32" /> representing the source entity identifier.</param> /// <param name="sourceEntityTypeId">A <see cref="System.Int32" /> representing the source entity type identifier.</param> /// <param name="relatedEntityTypeId">A <see cref="System.Int32" /> representing the related target entity type identifier.</param> /// <param name="purposeKey">The purpose key.</param> /// <returns> /// Returns a queryable collection of <see cref="Rock.Data.IEntity" /> entities. /// </returns> public IQueryable <IEntity> GetRelatedToSource(int sourceEntityId, int sourceEntityTypeId, int relatedEntityTypeId, string purposeKey) { EntityTypeCache relatedEntityTypeCache = EntityTypeCache.Get(relatedEntityTypeId); if (relatedEntityTypeCache.AssemblyName != null) { IQueryable <RelatedEntity> query = GetRelatedEntityRecordsToSource(sourceEntityId, sourceEntityTypeId, relatedEntityTypeId, purposeKey); var rockContext = this.Context as RockContext; Type relatedEntityType = relatedEntityTypeCache.GetEntityType(); if (relatedEntityType != null) { Rock.Data.IService serviceInstance = Reflection.GetServiceForEntityType(relatedEntityType, rockContext); MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; entityQry = query.Join( entityQry, f => f.TargetEntityId, e => e.Id, (f, e) => e); return(entityQry); } } return(null); }
/// <summary> /// Initializes a new instance of the <see cref="AttributeFieldAttribute"/> class. /// </summary> /// <param name="entityTypeGuid">The entity type unique identifier.</param> /// <param name="name">The name.</param> /// <param name="description">The description.</param> /// <param name="entityTypeQualifierColumn">The entity type qualifier column.</param> /// <param name="entityTypeQualifierValue">The entity type qualifier value.</param> /// <param name="required">if set to <c>true</c> [required].</param> /// <param name="allowMultiple">if set to <c>true</c> [allow multiple].</param> /// <param name="defaultValue">The default value.</param> /// <param name="category">The category.</param> /// <param name="order">The order.</param> /// <param name="key">The key.</param> public AttributeFieldAttribute(string entityTypeGuid, string entityTypeQualifierColumn, string entityTypeQualifierValue, string name, string description = "", bool required = true, bool allowMultiple = false, string defaultValue = "", string category = "", int order = 0, string key = null) : base(name, description, required, defaultValue, category, order, key, typeof(Rock.Field.Types.AttributeFieldType).FullName) { var entityTypeConfigValue = new Field.ConfigurationValue(entityTypeGuid); FieldConfigurationValues.Add(ENTITY_TYPE_KEY, entityTypeConfigValue); var allowMultipleConfigValue = new Field.ConfigurationValue(allowMultiple.ToString()); FieldConfigurationValues.Add(ALLOW_MULTIPLE_KEY, allowMultipleConfigValue); var entityTypeQualifierColumnConfigValue = new Field.ConfigurationValue(entityTypeQualifierColumn); FieldConfigurationValues.Add(QUALIFIER_COLUMN_KEY, entityTypeQualifierColumnConfigValue); if (entityTypeQualifierColumn.EndsWith("Id") && entityTypeQualifierValue.AsGuid() != Guid.Empty) { EntityTypeCache itemEntityType = EntityTypeCache.Get("Rock.Model." + entityTypeQualifierColumn.Left(entityTypeQualifierColumn.Length - 2)); if (itemEntityType.AssemblyName != null) { // get the actual type of what is being followed Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { var dbContext = Reflection.GetDbContextForEntityType(entityType); if (dbContext != null) { var serviceInstance = Reflection.GetServiceForEntityType(entityType, dbContext); if (serviceInstance != null) { MethodInfo getMethod = serviceInstance.GetType().GetMethod("Get", new Type[] { typeof(Guid) }); var entity = getMethod.Invoke(serviceInstance, new object[] { entityTypeQualifierValue.AsGuid() }) as Rock.Data.IEntity; if (entity != null) { FieldConfigurationValues.Add(QUALIFIER_VALUE_KEY, new Field.ConfigurationValue(entity.Id.ToString())); } } } } } } else { var entityTypeQualifierValueConfigValue = new Field.ConfigurationValue(entityTypeQualifierValue); FieldConfigurationValues.Add(QUALIFIER_VALUE_KEY, entityTypeQualifierValueConfigValue); } if (string.IsNullOrWhiteSpace(Name)) { var entityType = EntityTypeCache.Get(new Guid(entityTypeGuid)); name = (entityType != null ? entityType.Name : "Entity") + " Attribute"; } if (string.IsNullOrWhiteSpace(Key)) { Key = Name.Replace(" ", string.Empty); } }
public override bool Execute(RockContext rockContext, WorkflowAction action, object entity, out List <string> errorMessages) { errorMessages = new List <string>(); EntityTypeCache cachedEntityType = EntityTypeCache.Read(GetAttributeValue(action, "EntityType").AsGuid()); if (cachedEntityType != null) { Type entityType = cachedEntityType.GetEntityType(); var newEntity = (IEntity)Activator.CreateInstance(entityType); var propertyValues = GetAttributeValue(action, "EntityProperties").Replace(" ! ", " | ").ResolveMergeFields(GetMergeFields(action)).TrimEnd('|').Split('|').Select(p => p.Split('^')).Select(p => new { Name = p[0], Value = p[1] }); foreach (var prop in propertyValues) { PropertyInfo propInf = entityType.GetProperty(prop.Name, BindingFlags.Public | BindingFlags.Instance); if (null != propInf && propInf.CanWrite) { if (!(GetAttributeValue(action, "EmptyValueHandling") == "IGNORE" && string.IsNullOrWhiteSpace(prop.Value))) { try { propInf.SetValue(newEntity, ObjectConverter.ConvertObject(prop.Value, propInf.PropertyType, GetAttributeValue(action, "EmptyValueHandling") == "NULL"), null); } catch (Exception ex) when(ex is InvalidCastException || ex is FormatException || ex is OverflowException) { errorMessages.Add("Invalid Property Value: " + prop.Name + ": " + ex.Message); } } } else { errorMessages.Add("Invalid Property: " + prop.Name); } } rockContext.Set(entityType).Add(newEntity); rockContext.SaveChanges(); // If request attribute was specified, requery the request and set the attribute's value Guid?entityAttributeGuid = GetAttributeValue(action, "EntityAttribute").AsGuidOrNull(); if (entityAttributeGuid.HasValue) { newEntity = (IEntity)rockContext.Set(entityType).Find(new[] { newEntity.Id }); if (newEntity != null) { SetWorkflowAttributeValue(action, entityAttributeGuid.Value, newEntity.Guid.ToString()); } } return(true); } errorMessages.Add("Invalid Entity Attribute"); return(false); }
/// <summary> /// Adds the entity. /// </summary> /// <param name="entityType">Type of the entity.</param> /// <param name="entityId">The entity identifier.</param> public void AddEntity(EntityTypeCache entityType, int entityId) { var lazyEntity = new Lazy <IEntity>(() => { try { var dbContext = Reflection.GetDbContextForEntityType(entityType.GetEntityType()); var serviceInstance = Reflection.GetServiceForEntityType(entityType.GetEntityType(), dbContext); var getMethod = serviceInstance.GetType().GetMethod("Get", new[] { typeof(int) }); return(( IEntity )getMethod?.Invoke(serviceInstance, new object[] { entityId })); } catch { return(null); } }); _backingDictionary.Add(entityType.FriendlyName.Replace(" ", ""), lazyEntity); }
/// <summary> /// Gets the entity query /// For example: If the EntityTypeId is GroupMember, this will return a GroupMember query of group members that the person is following /// </summary> /// <param name="entityTypeId">The entity type identifier.</param> /// <param name="personId">The person identifier.</param> /// <param name="purposeKey">A purpose that defines how this following will be used.</param> /// <returns></returns> public IQueryable <IEntity> GetFollowedItems(int entityTypeId, int personId, string purposeKey) { EntityTypeCache itemEntityType = EntityTypeCache.Get(entityTypeId); var rockContext = this.Context as RockContext; purposeKey = purposeKey ?? string.Empty; var followedItemsQry = this.Queryable() .Where(a => a.PersonAlias.PersonId == personId && a.EntityTypeId == entityTypeId) .Where(f => (f.PurposeKey == null && purposeKey == "") || f.PurposeKey == purposeKey); if (itemEntityType.AssemblyName != null) { Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { Rock.Data.IService serviceInstance = Reflection.GetServiceForEntityType(entityType, rockContext); MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; entityQry = followedItemsQry.Join( entityQry, f => f.EntityId, e => e.Id, (f, e) => e); int personEntityTypeId = EntityTypeCache.Get <Rock.Model.Person>().Id; int personAliasEntityTypeId = EntityTypeCache.Get <Rock.Model.PersonAlias>().Id; // if requesting persons that the person is following, it is probably recorded as the PersonAlias records that the person is following, so get Person from that if (entityTypeId == personEntityTypeId) { var followedItemsPersonAliasQry = this.Queryable().Where(a => a.PersonAlias.PersonId == personId && a.EntityTypeId == personAliasEntityTypeId); var entityPersonAliasQry = new PersonAliasService(rockContext).Queryable(); var entityFollowedPersons = followedItemsPersonAliasQry.Join( entityPersonAliasQry, f => f.EntityId, e => e.Id, (f, e) => e).Select(a => a.Person); entityQry = entityQry.Union(entityFollowedPersons as IQueryable <IEntity>); } return(entityQry); } } return(null); }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnInit(EventArgs e) { base.OnInit(e); gReport.DataKeyNames = new string[] { "Id" }; gReport.Actions.ShowAdd = false; gReport.GridRebind += gReport_GridRebind; gReport.Actions.AddClick += gReport_AddClick; TagId = PageParameter("TagId").AsIntegerOrNull(); if (TagId.HasValue && TagId.Value > 0) { Tag _tag = new TagService(new RockContext()).Get(TagId.Value); if (_tag != null && _tag.IsAuthorized(Authorization.VIEW, CurrentPerson)) { pnlGrid.Visible = true; lTaggedTitle.Text = "Tagged Items"; TagEntityType = EntityTypeCache.Get(_tag.EntityTypeId ?? 0); if (TagEntityType != null) { if (TagEntityType.Name == "Rock.Model.Person") { gReport.ColumnsOfType <SelectField>().First().Visible = true; gReport.PersonIdField = "PersonId"; gReport.EntityIdField = "PersonId"; gReport.Actions.ShowAdd = _tag.IsAuthorized(Rock.Security.Authorization.TAG, CurrentPerson); } var entityType = TagEntityType.GetEntityType(); if (entityType != null) { lTaggedTitle.Text = "Tagged " + entityType.Name.Pluralize().SplitCase(); gReport.ColumnsOfType <RockTemplateField>().First(c => c.HeaderText == "Item").HeaderText = entityType.Name.SplitCase(); } } gReport.ColumnsOfType <DeleteField>().First().Visible = _tag.IsAuthorized(Rock.Security.Authorization.TAG, CurrentPerson); if (!Page.IsPostBack) { BindGrid(); } } else { pnlGrid.Visible = false; } } }
/// <summary> /// Handles the Click event of the btnShowDataPreview control. /// </summary> /// <param name="sender">The source of the event.</param> /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> protected void btnShowDataPreview_Click(object sender, EventArgs e) { if (pnlPreview.Visible) { pnlPreview.Visible = false; return; } var rockContext = new RockContext(); int entitySetId = hfEntitySetId.Value.AsInteger(); var entitySetService = new EntitySetService(rockContext); var entitySet = entitySetService.Get(entitySetId); if (entitySet.EntityTypeId.HasValue) { var qry = entitySetService.GetEntityQuery(entitySetId).Take(15); EntityTypeCache itemEntityType = EntityTypeCache.Read(entitySet.EntityTypeId ?? 0); gPreview.CreatePreviewColumns(itemEntityType.GetEntityType()); gPreview.DataSource = qry.ToList(); gPreview.DataBind(); } else { var entitySetItemService = new EntitySetItemService(rockContext); var qry = entitySetItemService.GetByEntitySetId(entitySetId, true).Take(15); var list = qry.ToList().Select(a => a.AdditionalMergeValuesJson.FromJsonOrNull <Dictionary <string, object> >()).ToList(); if (list.Any()) { gPreview.Columns.Clear(); foreach (var s in list[0]) { var gridField = Grid.GetGridField(s.Value != null ? s.Value.GetType() : typeof(string)); gridField.HeaderText = s.Key.SplitCase(); gridField.DataField = s.Key; gPreview.Columns.Add(gridField); } gPreview.DataSource = qry.ToList().Select(a => a.AdditionalMergeValuesJson.FromJsonOrNull <object>()).ToList(); gPreview.DataBind(); } } pnlPreview.Visible = true; }
/// <summary> /// Raises the <see cref="E:System.Web.UI.Control.Init" /> event. /// </summary> /// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param> protected override void OnInit(EventArgs e) { base.OnInit(e); gReport.DataKeyNames = new string[] { "Guid" }; gReport.GridRebind += gReport_GridRebind; int tagId = int.MinValue; if (int.TryParse(PageParameter("tagId"), out tagId) && tagId > 0) { Tag _tag = new TagService().Get(tagId); if (_tag != null) { TagId = tagId; TagEntityType = EntityTypeCache.Read(_tag.EntityTypeId); if (TagEntityType != null) { Type modelType = TagEntityType.GetEntityType(); lTaggedTitle.Text = "Tagged " + modelType.Name.Pluralize(); if (modelType != null) { Dictionary <string, BoundField> boundFields = gReport.Columns.OfType <BoundField>().ToDictionary(a => a.DataField); foreach (var column in gReport.GetPreviewColumns(modelType)) { int insertPos = gReport.Columns.IndexOf(gReport.Columns.OfType <DeleteField>().First()); gReport.Columns.Insert(insertPos, column); } if (TagEntityType.Name == "Rock.Model.Person") { gReport.PersonIdField = "Id"; } BindGrid(); } } } } }
/// <summary> /// Gets the entity query, ordered by the EntitySetItem.Order /// For example: If the EntitySet.EntityType is Person, this will return a Person Query of the items in this set /// </summary> /// <param name="entitySetId">The entity set identifier.</param> /// <returns></returns> public IQueryable <IEntity> GetEntityQuery(int entitySetId) { var entitySet = this.Get(entitySetId); if (entitySet?.EntityTypeId == null) { // the EntitySet Items are not IEntity items return(null); } EntityTypeCache itemEntityType = EntityTypeCache.Get(entitySet.EntityTypeId.Value); var rockContext = this.Context as RockContext; var entitySetItemsService = new EntitySetItemService(rockContext); var entityItemQry = entitySetItemsService.Queryable().Where(a => a.EntitySetId == entitySetId).OrderBy(a => a.Order); bool isPersonEntitySet = itemEntityType.Guid == Rock.SystemGuid.EntityType.PERSON.AsGuid(); if (itemEntityType.AssemblyName != null) { Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); Rock.Data.IService serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { rockContext }) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; var joinQry = entityItemQry.Join(entityQry, k => k.EntityId, i => i.Id, (setItem, item) => new { Item = item, ItemOrder = setItem.Order } ).OrderBy(a => a.ItemOrder).ThenBy(a => a.Item.Id); return(joinQry.Select(a => a.Item)); } } return(null); }
/// <summary> /// Gets a Service Queryable method for a particular entity type /// </summary> /// <param name="entityTypeId">The entity type identifier.</param> /// <returns></returns> private IQueryable <IEntity> GetQueryable(int entityTypeId) { EntityTypeCache itemEntityType = EntityTypeCache.Get(entityTypeId); if (itemEntityType != null) { Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { Type[] modelType = { entityType }; Type genericServiceType = typeof(Rock.Data.Service <>); Type modelServiceType = genericServiceType.MakeGenericType(modelType); var serviceInstance = Activator.CreateInstance(modelServiceType, new object[] { ( RockContext )this.Context }) as IService; MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); return(qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>); } } return(null); }
/// <summary> /// Returns a queryable collection of <see cref="Rock.Data.IEntity"/> source entities (related to the given target entity) for the given entity type and (optionally) also have a matching purpose key. /// </summary> /// <param name="targetEntityId">A <see cref="System.Int32" /> representing the target entity identifier.</param> /// <param name="targetEntityTypeId">A <see cref="System.Int32" /> representing the <see cref="RelatedEntity.TargetEntityTypeId"/></param> /// <param name="relatedEntityTypeId">A <see cref="System.Int32" /> representing the related <see cref="RelatedEntity.SourceEntityTypeId"/></param> /// <param name="purposeKey">The purpose key.</param> /// <returns> /// Returns a queryable collection of <see cref="Rock.Data.IEntity" /> entities. /// </returns> public IQueryable <IEntity> GetRelatedToTarget(int targetEntityId, int targetEntityTypeId, int relatedEntityTypeId, string purposeKey) { EntityTypeCache relatedEntityTypeCache = EntityTypeCache.Get(relatedEntityTypeId); if (relatedEntityTypeCache.AssemblyName != null) { var query = Queryable() .Where(a => a.TargetEntityTypeId == targetEntityTypeId && a.TargetEntityId == targetEntityId && a.SourceEntityTypeId == relatedEntityTypeId); if (purposeKey.IsNullOrWhiteSpace()) { query = query.Where(a => string.IsNullOrEmpty(a.PurposeKey)); } else { query = query.Where(a => a.PurposeKey == purposeKey); } var rockContext = this.Context as RockContext; Type relatedEntityType = relatedEntityTypeCache.GetEntityType(); if (relatedEntityType != null) { Rock.Data.IService serviceInstance = Reflection.GetServiceForEntityType(relatedEntityType, rockContext); MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; entityQry = query.Join( entityQry, f => f.SourceEntityId, e => e.Id, (f, e) => e); return(entityQry); } } return(null); }
/// <summary> /// Executes the specified context. /// </summary> /// <param name="context">The context.</param> public void Execute(IJobExecutionContext context) { JobDataMap dataMap = context.JobDetail.JobDataMap; Guid? groupGuid = dataMap.GetString("EligibleFollowers").AsGuidOrNull(); Guid? systemEmailGuid = dataMap.GetString("EmailTemplate").AsGuidOrNull(); int followingEventsSent = 0; if (groupGuid.HasValue && systemEmailGuid.HasValue) { var exceptionMsgs = new List <string>(); using (var rockContext = new RockContext()) { var followingService = new FollowingService(rockContext); var followingEventTypeService = new FollowingEventTypeService(rockContext); var followingEventNotificationService = new FollowingEventNotificationService(rockContext); // Get all the active event types var eventTypes = followingEventTypeService .Queryable().AsNoTracking() .Where(e => e.EntityTypeId.HasValue && e.IsActive) .OrderBy(e => e.Order) .ToList(); // Get the required event types var requiredEventTypes = eventTypes .Where(e => e.IsNoticeRequired) .ToList(); // The people who are eligible to get following event notices based on the group type setting for this job var eligiblePersonIds = new GroupMemberService(rockContext) .Queryable().AsNoTracking() .Where(m => m.Group != null && m.Group.Guid.Equals(groupGuid.Value) && m.GroupMemberStatus == GroupMemberStatus.Active && m.Person != null && m.Person.Email != null && m.Person.Email != string.Empty && m.Person.EmailPreference != EmailPreference.DoNotEmail && m.Person.IsEmailActive ) .Select(m => m.PersonId) .Distinct() .ToList(); // Get all the subscriptions for the eligible people var eventSubscriptions = new FollowingEventSubscriptionService(rockContext) .Queryable("PersonAlias").AsNoTracking() .Where(f => eligiblePersonIds.Contains(f.PersonAlias.PersonId)) .ToList(); // Dictionaries used to store information that will be used to create notification var personSubscriptions = new Dictionary <int, List <int> >(); // Key: personId, Value: list of event type ids that person subscribes to var personFollowings = new Dictionary <int, List <int> >(); // Key: personId, Value: list of following ids that person follows var eventsThatHappened = new Dictionary <int, Dictionary <int, string> >(); // Key: event type id Value: Dictionary of entity id and formatted event notice for the entity //Get the subscriptions for each person foreach (int personId in eligiblePersonIds) { var personEventTypes = eventSubscriptions .Where(s => s.PersonAlias.PersonId == personId) .Select(s => s.EventType) .ToList(); personEventTypes.AddRange(requiredEventTypes); if (personEventTypes.Any()) { personSubscriptions.AddOrIgnore(personId, personEventTypes .OrderBy(e => e.Order) .ThenBy(e => e.Name) .Select(e => e.Id) .Distinct() .ToList()); } } // Get a distinct list of each entitytype/entity that is being followed by anyone that subscribes to events var followings = followingService .Queryable("PersonAlias").AsNoTracking() .Where(f => personSubscriptions.Keys.Contains(f.PersonAlias.PersonId)) .ToList(); // group the followings by their type var followedEntityIds = new Dictionary <int, List <int> >(); foreach (var followedEntity in followings .Select(f => new { f.EntityTypeId, f.EntityId }) .Distinct()) { followedEntityIds.AddOrIgnore(followedEntity.EntityTypeId, new List <int>()); followedEntityIds[followedEntity.EntityTypeId].Add(followedEntity.EntityId); } // group the followings by the follower foreach (int personId in personSubscriptions.Select(s => s.Key)) { var personFollowing = followings .Where(f => f.PersonAlias.PersonId == personId) .Select(f => f.Id) .ToList(); personFollowings.Add(personId, personFollowing); } var timestamp = RockDateTime.Now; // foreach followed entitytype foreach (var keyVal in followedEntityIds) { // Get the entitytype EntityTypeCache itemEntityType = EntityTypeCache.Get(keyVal.Key); if (itemEntityType != null && itemEntityType.AssemblyName != null) { // get the actual type of what is being followed Type entityType = itemEntityType.GetEntityType(); if (entityType != null) { var dbContext = Reflection.GetDbContextForEntityType(entityType); if (dbContext != null) { var serviceInstance = Reflection.GetServiceForEntityType(entityType, dbContext); if (serviceInstance != null) { MethodInfo qryMethod = serviceInstance.GetType().GetMethod("Queryable", new Type[] { }); var entityQry = qryMethod.Invoke(serviceInstance, new object[] { }) as IQueryable <IEntity>; // If looking at person alias following, make sure to exclude deceased people if (entityType == typeof(Rock.Model.PersonAlias)) { var personAliasQry = entityQry as IQueryable <PersonAlias>; if (personAliasQry != null) { entityQry = personAliasQry.Where(p => !p.Person.IsDeceased); } } var entityList = entityQry.Where(q => keyVal.Value.Contains(q.Id)).ToList(); // If there are any followed entities of this type if (entityList.Any()) { // Get the active event types for this entity type foreach (var eventType in eventTypes.Where(e => e.FollowedEntityTypeId == keyVal.Key)) { try { // Get the component var eventComponent = eventType.GetEventComponent(); if (eventComponent != null) { // Get the previous notifications for this event type var previousNotifications = followingEventNotificationService .Queryable() .Where(n => n.FollowingEventTypeId == eventType.Id) .ToList(); // check each entity that is followed (by anyone) foreach (IEntity entity in entityList) { var previousNotification = previousNotifications .Where(n => n.EntityId == entity.Id) .FirstOrDefault(); DateTime?lastNotification = previousNotification != null ? previousNotification.LastNotified : (DateTime?)null; // If ok to send on this day var today = RockDateTime.Today; if (eventType.SendOnWeekends || (today.DayOfWeek != DayOfWeek.Saturday && today.DayOfWeek != DayOfWeek.Sunday)) { // if the event happened if (eventComponent.HasEventHappened(eventType, entity, lastNotification)) { // Store the event type id and the entity for later processing of notifications eventsThatHappened.AddOrIgnore(eventType.Id, new Dictionary <int, string>()); eventsThatHappened[eventType.Id].Add(entity.Id, eventComponent.FormatEntityNotification(eventType, entity)); if (previousNotification == null) { previousNotification = new FollowingEventNotification(); previousNotification.FollowingEventTypeId = eventType.Id; previousNotification.EntityId = entity.Id; followingEventNotificationService.Add(previousNotification); } previousNotification.LastNotified = timestamp; } } } rockContext.SaveChanges(); } eventType.LastCheckDateTime = RockDateTime.Now; } catch (Exception ex) { exceptionMsgs.Add(string.Format("An exception occurred calculating events for the '{0}' suggestion type:{1} {2}", eventType.Name, Environment.NewLine, ex.Messages().AsDelimited(Environment.NewLine + " "))); ExceptionLogService.LogException(ex, System.Web.HttpContext.Current); } } } } } } } } // send notifications var possibleRecipients = new PersonService(rockContext) .Queryable().AsNoTracking() .Where(p => personSubscriptions.Keys.Contains(p.Id)) .ToList(); // Loop through the possible recipients that actually subscribe to events foreach (var personSubscription in personSubscriptions) { // Get the recipient person int personId = personSubscription.Key; var person = possibleRecipients.Where(p => p.Id == personId).FirstOrDefault(); if (person != null) { try { // Make sure person is actually following anything if (personFollowings.ContainsKey(personId)) { // Dictionary to store the entities that had an event for each event type var personEventTypeNotices = new List <FollowingEventTypeNotices>(); // Get the event types that person subscribes to foreach (var eventType in eventsThatHappened.Where(e => personSubscription.Value.Contains(e.Key))) { // Get the EntityTypeId for this event type int entityTypeId = eventTypes .Where(e => e.Id == eventType.Key) .Select(e => e.FollowedEntityTypeId.Value) .FirstOrDefault(); // Find all the entities with this event type that the person follows var personFollowedEntityIds = followings .Where(f => personFollowings[personId].Contains(f.Id) && f.EntityTypeId == entityTypeId) .Select(f => f.EntityId) .ToList(); // Get any of those entities that had an event happen var personFollowedEntities = eventType.Value .Where(e => personFollowedEntityIds.Contains(e.Key)) .ToList(); // If any were found if (personFollowedEntities.Any()) { // Add the entry var eventTypeObj = eventTypes.Where(e => e.Id == eventType.Key).FirstOrDefault(); if (eventTypeObj != null) { personEventTypeNotices.Add(new FollowingEventTypeNotices(eventTypeObj, personFollowedEntities.Select(e => e.Value).ToList())); } } } // If there are any events for any of the entities that this person follows, send a notification if (personEventTypeNotices.Any()) { // Send the notice var mergeFields = new Dictionary <string, object>(); mergeFields.Add("Person", person); mergeFields.Add("EventTypes", personEventTypeNotices.OrderBy(e => e.EventType.Order).ToList()); var emailMessage = new RockEmailMessage(systemEmailGuid.Value); emailMessage.AddRecipient(new RockEmailMessageRecipient(person, mergeFields)); var errors = new List <string>(); emailMessage.Send(out errors); exceptionMsgs.AddRange(errors); if (!errors.Any()) { followingEventsSent++; } } } } catch (Exception ex) { exceptionMsgs.Add(string.Format("An exception occurred sending event notice to '{0}':{1} {2}", person.FullName, Environment.NewLine, ex.Messages().AsDelimited(Environment.NewLine + " "))); ExceptionLogService.LogException(ex, System.Web.HttpContext.Current); } } } } context.Result = string.Format("{0} following events emails sent", followingEventsSent); if (exceptionMsgs.Any()) { throw new Exception("One or more exceptions occurred calculating following events..." + Environment.NewLine + exceptionMsgs.AsDelimited(Environment.NewLine)); } } }
private void ShowData(Guid?categoryGuid, int?entityTypeId) { if (EntityCategories == null) { LoadCategories(); } hfSelectedCategoryGuid.Value = categoryGuid.ToString(); hfSelectedEntityId.Value = null; // Bind Categories rptCategory.DataSource = EntityCategories; rptCategory.DataBind(); pnlModels.Visible = false; pnlKey.Visible = false; lCategoryName.Text = string.Empty; EntityTypeCache entityType = null; var entityTypeList = new List <EntityTypeCache>(); if (categoryGuid.HasValue) { var category = EntityCategories.Where(c => c.Guid.Equals(categoryGuid)).FirstOrDefault(); if (category != null) { lCategoryName.Text = category.Name + " Models"; pnlModels.Visible = true; entityTypeList = category.RockEntityIds.Select(a => EntityTypeCache.Read(a)).Where(a => a != null).ToList(); if (entityTypeId.HasValue) { entityType = entityTypeList.Where(t => t.Id == entityTypeId.Value).FirstOrDefault(); hfSelectedEntityId.Value = entityType != null?entityType.Id.ToString() : null; } else { entityType = entityTypeList.FirstOrDefault(); hfSelectedEntityId.Value = entityTypeList.Any() ? entityTypeList.First().Id.ToString() : null; } } } // Bind Models rptModel.DataSource = entityTypeList; rptModel.DataBind(); string details = string.Empty; nbClassesWarning.Visible = false; if (entityType != null) { try { var type = entityType.GetEntityType(); if (type != null) { pnlKey.Visible = true; var xmlComments = GetXmlComments(); var mClass = new MClass(); mClass.Name = type.Name; mClass.Comment = GetComments(type, xmlComments); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | (BindingFlags.Instance)) .Where(m => (m.MemberType == MemberTypes.Method || m.MemberType == MemberTypes.Property)) .ToArray(); foreach (PropertyInfo p in properties.OrderBy(i => i.Name).ToArray()) { mClass.Properties.Add(new MProperty { Name = p.Name, IsInherited = p.DeclaringType != type, IsVirtual = p.GetGetMethod() != null && p.GetGetMethod().IsVirtual&& !p.GetGetMethod().IsFinal, IsLavaInclude = p.IsDefined(typeof(LavaIncludeAttribute)) || p.IsDefined(typeof(DataMemberAttribute)), NotMapped = p.IsDefined(typeof(NotMappedAttribute)), Required = p.IsDefined(typeof(RequiredAttribute)), Id = p.MetadataToken, Comment = GetComments(p, xmlComments) }); } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | (BindingFlags.Instance)) .Where(m => !m.IsSpecialName && (m.MemberType == MemberTypes.Method || m.MemberType == MemberTypes.Property)) .ToArray(); foreach (MethodInfo m in methods.OrderBy(i => i.Name).ToArray()) { // crazy, right? var param = string.Join(", ", m.GetParameters().Select(pi => { var x = pi.ParameterType + " " + pi.Name; return(x); })); mClass.Methods.Add(new MMethod { Name = m.Name, IsInherited = m.DeclaringType != type, Id = m.MetadataToken, Signature = string.Format("{0}({1})", m.Name, param), Comment = GetComments(m, xmlComments) }); } details = ClassNode(mClass); } else { nbClassesWarning.Text = "Unable to get class details for " + entityType.FriendlyName; nbClassesWarning.Details = entityType.AssemblyName; nbClassesWarning.Dismissable = true; nbClassesWarning.Visible = true; } } catch (Exception ex) { nbClassesWarning.Text = string.Format("Error getting class details for <code>{0}</code>", entityType); nbClassesWarning.Details = ex.Message; nbClassesWarning.Dismissable = true; nbClassesWarning.Visible = true; } } lClasses.Text = details; }
public IQueryable <TreeViewItem> GetChildren(string id, string additionalFields) { var person = GetPerson(); List <TreeViewItem> items = new List <TreeViewItem>(); switch (id) { case "0": { if (!string.IsNullOrWhiteSpace(additionalFields)) { foreach (string fieldInfo in additionalFields.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { string[] parts = fieldInfo.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); string fieldId = parts.Length > 0 ? parts[0] : string.Empty; if (fieldId == "AdditionalMergeFields") { if (parts.Length > 1) { var fieldsTv = new TreeViewItem { Id = $"AdditionalMergeFields_{parts[1]}", Name = "Additional Fields", HasChildren = true, Children = new List <TreeViewItem>() }; foreach (string fieldName in parts[1].Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries)) { fieldsTv.Children.Add(new TreeViewItem { Id = $"AdditionalMergeField_{fieldName}", Name = fieldName.SplitCase(), HasChildren = false }); } items.Add(fieldsTv); } } else { string[] idParts = fieldId.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); string mergeFieldId = idParts.Length > 1 ? idParts[1] : fieldId; var entityTypeInfo = MergeFieldPicker.GetEntityTypeInfoFromMergeFieldId(mergeFieldId); if (entityTypeInfo?.EntityType != null) { items.Add(new TreeViewItem { Id = fieldId.UrlEncode(), Name = parts.Length > 1 ? parts[1] : entityTypeInfo.EntityType.FriendlyName, HasChildren = true }); } else { items.Add(new TreeViewItem { Id = fieldId, Name = parts.Length > 1 ? parts[1] : mergeFieldId.SplitCase(), HasChildren = mergeFieldId == "GlobalAttribute" }); } } } } break; } case "GlobalAttribute": { var globalAttributes = GlobalAttributesCache.Get(); foreach (var attributeCache in globalAttributes.Attributes.OrderBy(a => a.Key)) { if (attributeCache.IsAuthorized(Authorization.VIEW, person)) { items.Add(new TreeViewItem { Id = "GlobalAttribute|" + attributeCache.Key, Name = attributeCache.Name, HasChildren = false }); } } break; } default: { // In this scenario, the id should be a concatenation of a root qualified entity name and then the property path var idParts = id.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (idParts.Count > 0) { // Get the root type int pathPointer = 0; EntityTypeCache entityType = null; MergeFieldPicker.EntityTypeInfo.EntityTypeQualifier[] entityTypeQualifiers = null; while (entityType == null && pathPointer < idParts.Count()) { string item = idParts[pathPointer]; string[] itemParts = item.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); string entityTypeMergeFieldId = itemParts.Length > 1 ? itemParts[1] : item; MergeFieldPicker.EntityTypeInfo entityTypeInfo = MergeFieldPicker.GetEntityTypeInfoFromMergeFieldId(entityTypeMergeFieldId); entityType = entityTypeInfo?.EntityType; entityTypeQualifiers = entityTypeInfo?.EntityTypeQualifiers; pathPointer++; } if (entityType != null) { Type type = entityType.GetEntityType(); // Traverse the Property path while (idParts.Count > pathPointer) { var childProperty = type.GetProperty(idParts[pathPointer]); if (childProperty != null) { type = childProperty.PropertyType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection <>) && type.GetGenericArguments().Length == 1) { type = type.GetGenericArguments()[0]; } } pathPointer++; } entityType = EntityTypeCache.Get(type); // Add the tree view items foreach (var propInfo in Rock.Lava.LavaHelper.GetLavaProperties(type)) { var treeViewItem = new TreeViewItem { Id = id + "|" + propInfo.Name, Name = propInfo.Name.SplitCase() }; Type propertyType = propInfo.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(ICollection <>) && propertyType.GetGenericArguments().Length == 1) { treeViewItem.Name += " (Collection)"; propertyType = propertyType.GetGenericArguments()[0]; } bool hasChildren = false; if (EntityTypeCache.Get(propertyType.FullName, false) != null) { hasChildren = Rock.Lava.LavaHelper.GetLavaProperties(propertyType).Any(); } treeViewItem.HasChildren = hasChildren; items.Add(treeViewItem); } if (type == typeof(Rock.Model.Person)) { items.Add(new TreeViewItem { Id = id + "|" + "Campus", Name = "Campus" }); } if (entityType.IsEntity) { var attributeList = new AttributeService(new Rock.Data.RockContext()).GetByEntityTypeId(entityType.Id, false).ToAttributeCacheList(); if (entityTypeQualifiers?.Any() == true) { var qualifiedAttributeList = new List <AttributeCache>(); foreach (var entityTypeQualifier in entityTypeQualifiers) { var qualifierAttributes = attributeList.Where(a => a.EntityTypeQualifierColumn.Equals(entityTypeQualifier.Column, StringComparison.OrdinalIgnoreCase) && a.EntityTypeQualifierValue.Equals(entityTypeQualifier.Value, StringComparison.OrdinalIgnoreCase)).ToList(); qualifiedAttributeList.AddRange(qualifierAttributes); } attributeList = qualifiedAttributeList; } else { // Only include attributes without a qualifier since we weren't specified a qualifiercolumn/value attributeList = attributeList.Where(a => a.EntityTypeQualifierColumn.IsNullOrWhiteSpace() && a.EntityTypeQualifierValue.IsNullOrWhiteSpace()).ToList(); } foreach (var attribute in attributeList) { if (attribute.IsAuthorized(Authorization.VIEW, person)) { items.Add(new TreeViewItem { Id = id + "|" + attribute.Key, Name = attribute.Name }); } } } } } break; } } return(items.OrderBy(i => i.Name).AsQueryable()); }
public IQueryable <TreeViewItem> GetChildren(string id, string additionalFields) { var person = GetPerson(); List <TreeViewItem> items = new List <TreeViewItem>(); switch (id) { case "0": { if (!string.IsNullOrWhiteSpace(additionalFields)) { foreach (string fieldInfo in additionalFields.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) { string[] parts = fieldInfo.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries); string fieldId = parts.Length > 0 ? parts[0] : string.Empty; string[] idParts = fieldId.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); string fieldType = idParts.Length > 1 ? idParts[1] : fieldId; var entityType = EntityTypeCache.Read(fieldType, false); if (entityType != null) { items.Add(new TreeViewItem { Id = fieldId, Name = parts.Length > 1 ? parts[1] : entityType.FriendlyName, HasChildren = true }); } else { items.Add(new TreeViewItem { Id = fieldId, Name = parts.Length > 1 ? parts[1] : fieldType.SplitCase(), HasChildren = fieldType == "GlobalAttribute" }); } } } break; } case "GlobalAttribute": { var globalAttributes = Rock.Web.Cache.GlobalAttributesCache.Read(); foreach (var attributeCache in globalAttributes.Attributes.OrderBy(a => a.Key)) { if (attributeCache.IsAuthorized(Authorization.VIEW, person)) { items.Add(new TreeViewItem { Id = "GlobalAttribute|" + attributeCache.Key, Name = attributeCache.Name, HasChildren = false }); } } break; } default: { // In this scenario, the id should be a concatnation of a root qualified entity name and then the property path var idParts = id.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (idParts.Count > 0) { // Get the root type int pathPointer = 0; EntityTypeCache entityType = null; while (entityType == null && pathPointer < idParts.Count()) { string item = idParts[pathPointer]; string[] itemParts = item.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); string itemType = itemParts.Length > 1 ? itemParts[1] : item; entityType = EntityTypeCache.Read(itemType, false); pathPointer++; } if (entityType != null) { Type type = entityType.GetEntityType(); // Traverse the Property path while (idParts.Count > pathPointer) { var childProperty = type.GetProperty(idParts[pathPointer]); if (childProperty != null) { type = childProperty.PropertyType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection <>) && type.GetGenericArguments().Length == 1) { type = type.GetGenericArguments()[0]; } } pathPointer++; } entityType = EntityTypeCache.Read(type); // Add the tree view items foreach (var propInfo in type.GetProperties()) { if (propInfo.GetCustomAttributes(typeof(System.Runtime.Serialization.DataMemberAttribute)).Count() > 0) { var treeViewItem = new TreeViewItem { Id = id + "|" + propInfo.Name, Name = propInfo.Name.SplitCase() }; Type propertyType = propInfo.PropertyType; if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(ICollection <>) && propertyType.GetGenericArguments().Length == 1) { treeViewItem.Name += " (Collection)"; propertyType = propertyType.GetGenericArguments()[0]; } bool hasChildren = false; if (EntityTypeCache.Read(propertyType.FullName, false) != null) { foreach (var childPropInfo in propertyType.GetProperties()) { if (childPropInfo.GetCustomAttributes(typeof(System.Runtime.Serialization.DataMemberAttribute)).Count() > 0) { hasChildren = true; break; } } } treeViewItem.HasChildren = hasChildren; items.Add(treeViewItem); } } if (entityType.IsEntity) { foreach (Rock.Model.Attribute attribute in new AttributeService(new Rock.Data.RockContext()).GetByEntityTypeId(entityType.Id)) { // Only include attributes without a qualifier (since we don't have a specific instance of this entity type) if (string.IsNullOrEmpty(attribute.EntityTypeQualifierColumn) && string.IsNullOrEmpty(attribute.EntityTypeQualifierValue) && attribute.IsAuthorized(Authorization.VIEW, person)) { items.Add(new TreeViewItem { Id = id + "|" + attribute.Key, Name = attribute.Name }); } } } } } break; } } return(items.OrderBy(i => i.Name).AsQueryable()); }
private void ShowData(Guid?categoryGuid, int?entityTypeId) { if (EntityCategories == null) { LoadCategories(); } hfSelectedCategoryGuid.Value = categoryGuid.ToString(); hfSelectedEntityId.Value = null; // Bind Categories rptCategory.DataSource = EntityCategories; rptCategory.DataBind(); pnlModels.Visible = false; pnlKey.Visible = false; lCategoryName.Text = string.Empty; EntityTypeCache entityType = null; var entityTypeList = new List <EntityTypeCache>(); if (categoryGuid.HasValue) { var category = EntityCategories.Where(c => c.Guid.Equals(categoryGuid)).FirstOrDefault(); if (category != null) { lCategoryName.Text = category.Name.SplitCase() + " Models"; pnlModels.Visible = true; entityTypeList = category .RockEntityIds .Select(a => EntityTypeCache.Get(a)) .Where(a => a != null) .OrderBy(et => et.FriendlyName) .ToList(); if (entityTypeId.HasValue) { entityType = entityTypeList.Where(t => t.Id == entityTypeId.Value).FirstOrDefault(); hfSelectedEntityId.Value = entityType != null?entityType.Id.ToString() : null; } else { entityType = entityTypeList.FirstOrDefault(); hfSelectedEntityId.Value = entityTypeList.Any() ? entityTypeList.First().Id.ToString() : null; } } } // Bind Models rptModel.DataSource = entityTypeList; rptModel.DataBind(); string details = string.Empty; nbClassesWarning.Visible = false; pnlClassDetail.Visible = false; if (entityType != null) { try { var type = entityType.GetEntityType(); if (type != null) { pnlKey.Visible = true; var xmlComments = GetXmlComments(); var mClass = new MClass(); mClass.Name = type.Name; mClass.Comment = GetComments(type, xmlComments); PropertyInfo[] properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.MemberType == MemberTypes.Method || m.MemberType == MemberTypes.Property) .ToArray(); foreach (PropertyInfo p in properties.OrderBy(i => i.Name).ToArray()) { #pragma warning disable CS0618 // LavaIncludeAttribute is obsolete var property = new MProperty { Name = p.Name, IsInherited = p.DeclaringType != type, IsVirtual = p.GetGetMethod() != null && p.GetGetMethod().IsVirtual&& !p.GetGetMethod().IsFinal, IsLavaInclude = p.IsDefined(typeof(LavaIncludeAttribute)) || p.IsDefined(typeof(LavaVisibleAttribute)) || p.IsDefined(typeof(DataMemberAttribute)), IsObsolete = p.IsDefined(typeof(ObsoleteAttribute)), ObsoleteMessage = GetObsoleteMessage(p), NotMapped = p.IsDefined(typeof(NotMappedAttribute)), Required = p.IsDefined(typeof(RequiredAttribute)), Id = p.MetadataToken, Comment = GetComments(p, xmlComments, properties), IsEnum = p.PropertyType.IsEnum, IsDefinedValue = p.Name.EndsWith("ValueId") && p.IsDefined(typeof(DefinedValueAttribute)) }; #pragma warning restore CS0618 // LavaIncludeAttribute is obsolete if (property.IsEnum) { property.KeyValues = new Dictionary <string, string>(); var values = p.PropertyType.GetEnumValues(); foreach (var value in values) { property.KeyValues.AddOrReplace((( int )value).ToString(), value.ToString()); } } else if (property.IsDefinedValue) { var definedValueAttribute = p.GetCustomAttribute <Rock.Data.DefinedValueAttribute>(); if (definedValueAttribute != null && definedValueAttribute.DefinedTypeGuid.HasValue) { property.KeyValues = new Dictionary <string, string>(); var definedTypeGuid = definedValueAttribute.DefinedTypeGuid.Value; var definedType = DefinedTypeCache.Get(definedTypeGuid); property.DefinedTypeId = definedType.Id; foreach (var definedValue in definedType.DefinedValues) { property.KeyValues.AddOrReplace(string.Format("{0} = {1}", definedValue.Id, definedValue.Value), definedValue.Description); } } } mClass.Properties.Add(property); } MethodInfo[] methods = type.GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => !m.IsSpecialName && (m.MemberType == MemberTypes.Method || m.MemberType == MemberTypes.Property)) .ToArray(); foreach (MethodInfo m in methods.OrderBy(i => i.Name).ToArray()) { // crazy, right? var param = string.Join(", ", m.GetParameters().Select(pi => { var x = pi.ParameterType + " " + pi.Name; return(x); })); mClass.Methods.Add(new MMethod { Name = m.Name, IsInherited = m.DeclaringType != type, Id = m.MetadataToken, Signature = string.Format("{0}({1})", m.Name, param), Comment = GetComments(m, xmlComments), IsObsolete = m.IsDefined(typeof(ObsoleteAttribute)), ObsoleteMessage = GetObsoleteMessage(m) }); } var pageReference = new Rock.Web.PageReference(CurrentPageReference); pageReference.QueryString = new System.Collections.Specialized.NameValueCollection(); pageReference.QueryString["EntityType"] = entityType.Guid.ToString(); lClassName.Text = mClass.Name; hlAnchor.NavigateUrl = pageReference.BuildUrl(); lClassDescription.Text = mClass.Comment != null ? mClass.Comment.Summary : string.Empty; lClasses.Text = ClassNode(mClass); pnlClassDetail.Visible = true; } else { nbClassesWarning.Text = "Unable to get class details for " + entityType.FriendlyName; nbClassesWarning.Details = entityType.AssemblyName; nbClassesWarning.Dismissable = true; nbClassesWarning.Visible = true; } } catch (Exception ex) { nbClassesWarning.Text = string.Format("Error getting class details for <code>{0}</code>", entityType); nbClassesWarning.Details = ex.Message; nbClassesWarning.Dismissable = true; nbClassesWarning.Visible = true; } } }
/// <summary> /// Formats the selected value (node path) into a liquid merge field. /// </summary> /// <param name="selectedValue">The selected value.</param> /// <returns></returns> public static string FormatSelectedValue(string selectedValue) { var idParts = selectedValue.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries).ToList(); if (idParts.Count > 0) { if (idParts.Count == 2 && idParts[0] == "GlobalAttribute") { return(string.Format("{{{{ 'Global' | Attribute:'{0}' }}}}", idParts[1])); } if (idParts.Count == 1 && idParts[0].StartsWith("AdditionalMergeField")) { string mFields = idParts[0].Replace("AdditionalMergeField_", "").Replace("AdditionalMergeFields_", ""); if (mFields.IsNotNullOrWhiteSpace()) { string beginFor = "{% for field in AdditionalFields %}"; string endFor = "{% endfor %}"; var mergeFields = String.Join("", mFields.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries) .Select(f => "{{ field." + f + "}}")); return($"{beginFor}{mergeFields}{endFor}"); } } if (idParts.Count == 1) { if (idParts[0] == "Campuses") { return(@" {% for campus in Campuses %} <p> Name: {{ campus.Name }}<br/> Description: {{ campus.Description }}<br/> Is Active: {{ campus.IsActive }}<br/> Short Code: {{ campus.ShortCode }}<br/> Url: {{ campus.Url }}<br/> Phone Number: {{ campus.PhoneNumber }}<br/> Service Times: {% for serviceTime in campus.ServiceTimes %} {{ serviceTime.Day }} {{ serviceTime.Time }}, {% endfor %} <br/> {% endfor %} "); } if (idParts[0] == "Date") { return("{{ 'Now' | Date:'MM/dd/yyyy' }}"); } if (idParts[0] == "Time") { return("{{ 'Now' | Date:'hh:mm:ss tt' }}"); } if (idParts[0] == "DayOfWeek") { return("{{ 'Now' | Date:'dddd' }}"); } if (idParts[0] == "PageParameter") { return("{{ PageParameter.[Enter Page Parameter Name Here] }}"); } } var workingParts = new List <string>(); // Get the root type int pathPointer = 0; EntityTypeCache entityType = null; while (entityType == null && pathPointer < idParts.Count()) { string item = idParts[pathPointer]; string[] itemParts = item.Split(new char[] { '^' }, StringSplitOptions.RemoveEmptyEntries); string itemName = itemParts.Length > 1 ? itemParts[0] : string.Empty; string mergeFieldId = itemParts.Length > 1 ? itemParts[1] : item; var entityTypeInfo = MergeFieldPicker.GetEntityTypeInfoFromMergeFieldId(mergeFieldId); entityType = entityTypeInfo?.EntityType; workingParts.Add(entityType != null ? (itemName != string.Empty ? itemName : entityType.FriendlyName.Replace(" ", string.Empty)) : idParts[pathPointer]); pathPointer++; } if (entityType != null) { Type type = entityType.GetEntityType(); var formatString = "{0}"; // Traverse the Property path bool itemIsCollection = false; bool lastItemIsProperty = true; while (idParts.Count > pathPointer) { string propertyName = idParts[pathPointer]; workingParts.Add(propertyName); var childProperty = type.GetProperty(propertyName); if (childProperty != null) { lastItemIsProperty = true; type = childProperty.PropertyType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ICollection <>) && type.GetGenericArguments().Length == 1) { string propertyNameSingularized = propertyName.Singularize(); string forString = string.Format("<% for {0} in {1} %> {{0}} <% endfor %>", propertyNameSingularized, workingParts.AsDelimited(".")); workingParts.Clear(); workingParts.Add(propertyNameSingularized); formatString = string.Format(formatString, forString); type = type.GetGenericArguments()[0]; itemIsCollection = true; } else { itemIsCollection = false; } } else { lastItemIsProperty = false; } pathPointer++; } string itemString = string.Empty; if (!itemIsCollection) { if (lastItemIsProperty) { itemString = string.Format("<< {0} >>", workingParts.AsDelimited(".")); } else { string partPath = workingParts.Take(workingParts.Count - 1).ToList().AsDelimited("."); var partItem = workingParts.Last(); if (type == typeof(Rock.Model.Person) && partItem == "Campus") { itemString = string.Format("{{{{ {0} | Campus | Property:'Name' }}}}", partPath); } else { itemString = string.Format("{{{{ {0} | Attribute:'{1}' }}}}", partPath, partItem); } } } return(string.Format(formatString, itemString).Replace("<", "{").Replace(">", "}")); } return(string.Format("{{{{ {0} }}}}", idParts.AsDelimited("."))); } return(string.Empty); }