/// <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);
        }
Пример #2
0
        /// <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);
        }
Пример #3
0
        /// <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);
        }
Пример #5
0
        /// <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);
            }
        }
Пример #6
0
        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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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;
                }
            }
        }
Пример #10
0
        /// <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;
        }
Пример #11
0
        /// <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();
                        }
                    }
                }
            }
        }
Пример #12
0
        /// <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);
        }
Пример #13
0
        /// <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);
        }
Пример #14
0
        /// <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);
        }
Пример #15
0
        /// <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));
                }
            }
        }
Пример #16
0
        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;
        }
Пример #17
0
        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());
        }
Пример #18
0
        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());
        }
Пример #19
0
        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;
                }
            }
        }
Пример #20
0
        /// <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);
        }