/// <summary> /// Sets the value of an attribute key in memory. Once values have been set, use the <see cref="SaveAttributeValues()" /> method to save all values to database /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> public void SetAttributeValue(string key, string value) { if (this is IEntityCache && this is IHasAttributes) { // if a compiled V7 Plugin is calling this, 'this' might actually be the new ModelCache<T,TT> (which we can detect if it is IEntityCache) and not the obsolete CachedModel<T> // so (this as IHasAttributes) will be the actual ModelCache<T,TT> instance that we can set the AttributeValue with (this as IHasAttributes).SetAttributeValue(key, value); return; } if (this.AttributeValues != null) { if (this.AttributeValues.ContainsKey(key)) { this.AttributeValues[key].Value = value; } else if (this.Attributes.ContainsKey(key)) { var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = this.Attributes[key].Id; attributeValue.Value = value; this.AttributeValues.Add(key, attributeValue); } } }
/// <summary> /// Sets the value of an attribute key in memory. Once values have been set, use the <see cref="SaveAttributeValues()" /> method to save all values to database /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> public void SetAttributeValue(string key, string value) { if (this.AttributeValues != null) { if (this.AttributeValues.ContainsKey(key)) { this.AttributeValues[key].Value = value; } else if (this.Attributes.ContainsKey(key)) { var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = this.Attributes[key].Id; attributeValue.Value = value; this.AttributeValues.Add(key, attributeValue); } } }
/// <summary> /// Sets the value of an attribute key in memory. Once values have been set, use the <see cref="SaveAttributeValues()" /> method to save all values to database /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> public void SetAttributeValue(string key, string value) { if (AttributeValues == null) { return; } if (AttributeValues.ContainsKey(key)) { AttributeValues[key].Value = value; } else if (Attributes.ContainsKey(key)) { var attributeValue = new AttributeValueCache { AttributeId = Attributes[key].Id, Value = value }; AttributeValues.Add(key, attributeValue); } }
private double HoursElapsed( WorkflowAction action ) { // Use the current action type' guid as the key for a 'DateTime Sent' attribute string AttrKey = action.ActionType.Guid.ToString() + "_DateTimeSent"; // Check to see if the action's activity does not yet have the the 'DateTime Sent' attribute. // The first time this action runs on any workflow instance using this action instance, the // attribute will not exist and need to be created if ( !action.Activity.Attributes.ContainsKey( AttrKey ) ) { var attribute = new Rock.Model.Attribute(); attribute.EntityTypeId = action.Activity.TypeId; attribute.EntityTypeQualifierColumn = "ActivityTypeId"; attribute.EntityTypeQualifierValue = action.Activity.ActivityTypeId.ToString(); attribute.Name = "DateTime Sent"; attribute.Key = AttrKey; attribute.FieldTypeId = FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ).Id; // Need to save the attribute now (using different context) so that an attribute id is returned. using ( var newRockContext = new RockContext() ) { new AttributeService( newRockContext ).Add( attribute ); newRockContext.SaveChanges(); } action.Activity.Attributes.Add( AttrKey, AttributeCache.Read( attribute ) ); var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = attribute.Id; attributeValue.Value = RockDateTime.Now.ToString( "o" ); action.Activity.AttributeValues.Add( AttrKey, attributeValue ); } else { // Check to see if this action instance has a value for the 'Delay Activated' attrbute DateTime? dateSent = action.Activity.GetAttributeValue( AttrKey ).AsDateTime(); if ( dateSent.HasValue ) { // If a value does exist, check to see if the number of minutes to delay has passed // since the value was saved return RockDateTime.Now.Subtract( dateSent.Value ).TotalHours; } else { // If no value exists, set the value to the current time action.Activity.SetAttributeValue( AttrKey, RockDateTime.Now.ToString( "o" ) ); } } return 0.0D; }
private string EmailStatus( WorkflowAction action ) { // Use the current action type' guid as the key for a 'Email Status' attribute string AttrKey = action.ActionType.Guid.ToString() + "_EmailStatus"; // Check to see if the action's activity does not yet have the the 'Email Status' attribute. // The first time this action runs on any workflow instance using this action instance, the // attribute will not exist and need to be created if ( !action.Activity.Attributes.ContainsKey( AttrKey ) ) { var attribute = new Rock.Model.Attribute(); attribute.EntityTypeId = action.Activity.TypeId; attribute.EntityTypeQualifierColumn = "ActivityTypeId"; attribute.EntityTypeQualifierValue = action.Activity.ActivityTypeId.ToString(); attribute.Name = "Email Status"; attribute.Key = AttrKey; attribute.FieldTypeId = FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ).Id; // Need to save the attribute now (using different context) so that an attribute id is returned. using ( var newRockContext = new RockContext() ) { new AttributeService( newRockContext ).Add( attribute ); newRockContext.SaveChanges(); } action.Activity.Attributes.Add( AttrKey, AttributeCache.Read( attribute ) ); var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = attribute.Id; attributeValue.Value = string.Empty; action.Activity.AttributeValues.Add( AttrKey, attributeValue ); } else { return action.Activity.GetAttributeValue( AttrKey ); } return string.Empty; }
/// <summary> /// Executes the specified workflow. /// </summary> /// <param name="rockContext">The rock context.</param> /// <param name="action">The action.</param> /// <param name="entity">The entity.</param> /// <param name="errorMessages">The error messages.</param> /// <returns></returns> public override bool Execute( RockContext rockContext, WorkflowAction action, Object entity, out List<string> errorMessages ) { errorMessages = new List<string>(); if ( entity is Model.BinaryFile ) { var binaryFile = (Model.BinaryFile) entity; if ( binaryFile.BinaryFileType.Guid != new Guid( SystemGuid.BinaryFiletype.CHECKIN_LABEL ) ) { errorMessages.Add( "Binary file is not a check-in label" ); action.AddLogEntry( "Binary file is not a check-in label", true ); return false; } binaryFile.LoadAttributes(); // Get the existing merge fields var existingMergeFields = new Dictionary<string, string>(); foreach ( var keyAndVal in binaryFile.GetAttributeValue( "MergeCodes" ).Split( new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries ) ) { var keyVal = keyAndVal.Split( new char[] { '^' } ); if ( keyVal.Length == 2 ) { existingMergeFields.AddOrIgnore( keyVal[0], keyVal[1] ); } } // Build new merge fields var newMergeFields = new List<string>(); foreach ( Match match in Regex.Matches( binaryFile.ContentsToString(), @"(?<=\^FD)((?!\^FS).)*(?=\^FS)" ) ) { string value = existingMergeFields.ContainsKey( match.Value ) ? existingMergeFields[match.Value] : ""; newMergeFields.Add( string.Format( "{0}^{1}", match.Value, value ) ); } // Save attribute value var attributeValue = new AttributeValueCache(); attributeValue.Value = newMergeFields.AsDelimited( "|" ); binaryFile.AttributeValues["MergeCodes"] = attributeValue; binaryFile.SaveAttributeValues( rockContext ); } return true; }
private DateTime GetDateTimeActivated( WorkflowAction action ) { var dateActivated = RockDateTime.Now; // Use the current action type' guid as the key for a 'Delay Activated' attribute string AttrKey = action.ActionType.Guid.ToString(); // Check to see if the action's activity does not yet have the the 'Delay Activated' attribute. // The first time this action runs on any workflow instance using this action instance, the // attribute will not exist and need to be created if ( !action.Activity.Attributes.ContainsKey( AttrKey ) ) { var attribute = new Rock.Model.Attribute(); attribute.EntityTypeId = action.Activity.TypeId; attribute.EntityTypeQualifierColumn = "ActivityTypeId"; attribute.EntityTypeQualifierValue = action.Activity.ActivityTypeId.ToString(); attribute.Name = "Delay Activated"; attribute.Key = AttrKey; attribute.FieldTypeId = FieldTypeCache.Read( Rock.SystemGuid.FieldType.TEXT.AsGuid() ).Id; // Need to save the attribute now (using different context) so that an attribute id is returned. using ( var newRockContext = new RockContext() ) { new AttributeService( newRockContext ).Add( attribute ); newRockContext.SaveChanges(); } action.Activity.Attributes.Add( AttrKey, AttributeCache.Read( attribute ) ); var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = attribute.Id; attributeValue.Value = dateActivated.ToString( "o" ); action.Activity.AttributeValues.Add( AttrKey, attributeValue ); action.AddLogEntry( string.Format( "Delay Activated at {0}", dateActivated), true ); } else { // Check to see if this action instance has a value for the 'Delay Activated' attrbute DateTime? activated = action.Activity.GetAttributeValue( AttrKey ).AsDateTime(); if ( activated.HasValue ) { return activated.Value; } else { // If no value exists, set the value to the current time action.Activity.SetAttributeValue( AttrKey, dateActivated.ToString( "o" ) ); action.AddLogEntry( string.Format( "Delay Activated at {0}", dateActivated ), true ); } } return dateActivated; }
/// <summary> /// Loads the <see cref="P:IHasAttributes.Attributes" /> and <see cref="P:IHasAttributes.AttributeValues" /> of any <see cref="IHasAttributes" /> object /// </summary> /// <param name="entity">The item.</param> /// <param name="rockContext">The rock context.</param> public static void LoadAttributes( Rock.Attribute.IHasAttributes entity, RockContext rockContext ) { if ( entity != null ) { Dictionary<string, PropertyInfo> properties = new Dictionary<string, PropertyInfo>(); Type entityType = entity.GetType(); if ( entityType.IsDynamicProxyType() ) { entityType = entityType.BaseType; } rockContext = rockContext ?? new RockContext(); // Event item's will load attributes for child calendar items. Use this to store the child values. var altEntityIds = new List<int>(); // Check for group type attributes var groupTypeIds = new List<int>(); if ( entity is GroupMember || entity is Group || entity is GroupType ) { // Can't use GroupTypeCache here since it loads attributes and would result in a recursive stack overflow situation var groupTypeService = new GroupTypeService( rockContext ); GroupType groupType = null; if ( entity is GroupMember ) { var group = ( (GroupMember)entity ).Group ?? new GroupService( rockContext ) .Queryable().AsNoTracking().FirstOrDefault(g => g.Id == ( (GroupMember)entity ).GroupId ); if ( group != null ) { groupType = group.GroupType ?? groupTypeService .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == group.GroupTypeId ); } } else if ( entity is Group ) { groupType = ( (Group)entity ).GroupType ?? groupTypeService .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( (Group)entity ).GroupTypeId ); } else { groupType = ( (GroupType)entity ); } while ( groupType != null ) { groupTypeIds.Insert( 0, groupType.Id ); // Check for inherited group type id's if ( groupType.InheritedGroupTypeId.HasValue ) { groupType = groupType.InheritedGroupType ?? groupTypeService .Queryable().AsNoTracking().FirstOrDefault( t => t.Id == ( groupType.InheritedGroupTypeId ?? 0 ) ); } else { groupType = null; } } } // Check for registration template type attributes int? registrationTemplateId = null; if ( entity is RegistrationRegistrant ) { RegistrationInstance registrationInstance = null; var registration = ( (RegistrationRegistrant)entity ).Registration ?? new RegistrationService( rockContext ) .Queryable().AsNoTracking().FirstOrDefault( r => r.Id == ( (RegistrationRegistrant)entity ).RegistrationId ); if ( registration != null ) { registrationInstance = registration.RegistrationInstance ?? new RegistrationInstanceService( rockContext ) .Queryable().AsNoTracking().FirstOrDefault( r => r.Id == registration.RegistrationInstanceId ); if ( registrationInstance != null ) { registrationTemplateId = registrationInstance.RegistrationTemplateId; } } } // Get the calendar ids for any event items var calendarIds = new List<int>(); if ( entity is EventItem ) { var calendarItems = ( (EventItem)entity ).EventCalendarItems.ToList() ?? new EventCalendarItemService( rockContext ) .Queryable().AsNoTracking().Where( c => c.EventItemId == ( (EventItem)entity ).Id ).ToList(); calendarIds = calendarItems.Select( c => c.EventCalendarId ).ToList(); altEntityIds = calendarItems.Select( c => c.Id ).ToList(); } foreach ( PropertyInfo propertyInfo in entityType.GetProperties() ) properties.Add( propertyInfo.Name.ToLower(), propertyInfo ); Rock.Model.AttributeService attributeService = new Rock.Model.AttributeService( rockContext ); Rock.Model.AttributeValueService attributeValueService = new Rock.Model.AttributeValueService( rockContext ); var inheritedAttributes = new Dictionary<int, List<Rock.Web.Cache.AttributeCache>>(); if ( groupTypeIds.Any() ) { groupTypeIds.ForEach( g => inheritedAttributes.Add( g, new List<Rock.Web.Cache.AttributeCache>() ) ); } else if ( calendarIds.Any() ) { calendarIds.ForEach( c => inheritedAttributes.Add( c, new List<Rock.Web.Cache.AttributeCache>() ) ); } else { inheritedAttributes.Add( 0, new List<Rock.Web.Cache.AttributeCache>() ); } // Check for any calendar item attributes that event item inherits if ( calendarIds.Any() ) { var calendarItemEntityType = EntityTypeCache.Read( typeof( EventCalendarItem ) ); if ( calendarItemEntityType != null ) { foreach ( var calendarItemEntityAttributes in AttributeCache .GetByEntity( calendarItemEntityType.Id ) .Where( a => a.EntityTypeQualifierColumn == "EventCalendarId" && calendarIds.Contains( a.EntityTypeQualifierValue.AsInteger() ) ) ) { foreach ( var attributeId in calendarItemEntityAttributes.AttributeIds ) { inheritedAttributes[calendarItemEntityAttributes.EntityTypeQualifierValue.AsInteger()].Add( AttributeCache.Read( attributeId ) ); } } } } var attributes = new List<Rock.Web.Cache.AttributeCache>(); // Get all the attributes that apply to this entity type and this entity's properties match any attribute qualifiers var entityTypeCache = Rock.Web.Cache.EntityTypeCache.Read( entityType); if ( entityTypeCache != null ) { int entityTypeId = entityTypeCache.Id; foreach ( var entityAttributes in AttributeCache.GetByEntity( entityTypeCache.Id ) ) { // group type ids exist (entity is either GroupMember, Group, or GroupType) and qualifier is for a group type id if ( groupTypeIds.Any() && ( ( entity is GroupMember && string.Compare( entityAttributes.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) || ( entity is Group && string.Compare( entityAttributes.EntityTypeQualifierColumn, "GroupTypeId", true ) == 0 ) || ( entity is GroupType && string.Compare( entityAttributes.EntityTypeQualifierColumn, "Id", true ) == 0 ) ) ) { int groupTypeIdValue = int.MinValue; if ( int.TryParse( entityAttributes.EntityTypeQualifierValue, out groupTypeIdValue ) && groupTypeIds.Contains( groupTypeIdValue ) ) { foreach( int attributeId in entityAttributes.AttributeIds ) { inheritedAttributes[groupTypeIdValue].Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) ); } } } // Registrant attribute ( by RegistrationTemplateId ) else if ( entity is RegistrationRegistrant && registrationTemplateId.HasValue && entityAttributes.EntityTypeQualifierValue.AsInteger() == registrationTemplateId.Value ) { foreach ( int attributeId in entityAttributes.AttributeIds ) { attributes.Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) ); } } else if ( string.IsNullOrEmpty( entityAttributes.EntityTypeQualifierColumn ) || ( properties.ContainsKey( entityAttributes.EntityTypeQualifierColumn.ToLower() ) && ( string.IsNullOrEmpty( entityAttributes.EntityTypeQualifierValue ) || ( properties[entityAttributes.EntityTypeQualifierColumn.ToLower()].GetValue( entity, null ) ?? "" ).ToString() == entityAttributes.EntityTypeQualifierValue ) ) ) { foreach( int attributeId in entityAttributes.AttributeIds ) { attributes.Add( Rock.Web.Cache.AttributeCache.Read( attributeId ) ); } } } } var allAttributes = new List<Rock.Web.Cache.AttributeCache>(); foreach ( var attributeGroup in inheritedAttributes ) { foreach ( var attribute in attributeGroup.Value ) { allAttributes.Add( attribute ); } } foreach ( var attribute in attributes ) { allAttributes.Add( attribute ); } var attributeValues = new Dictionary<string, AttributeValueCache>(); if ( allAttributes.Any() ) { foreach ( var attribute in allAttributes ) { // Add a placeholder for this item's value for each attribute attributeValues.AddOrIgnore( attribute.Key, null ); } // If loading attributes for a saved item, read the item's value(s) for each attribute if ( !entityTypeCache.IsEntity || entity.Id != 0 ) { List<int> attributeIds = allAttributes.Select( a => a.Id ).ToList(); foreach ( var attributeValue in attributeValueService.Queryable().AsNoTracking() .Where( v => v.EntityId.HasValue && ( v.EntityId.Value == entity.Id || altEntityIds.Contains( v.EntityId.Value ) ) && attributeIds.Contains( v.AttributeId ) ) ) { var attributeKey = AttributeCache.Read( attributeValue.AttributeId ).Key; attributeValues[attributeKey] = new AttributeValueCache( attributeValue ); } } // Look for any attributes that don't have a value and create a default value entry foreach ( var attribute in allAttributes ) { if ( attributeValues[attribute.Key] == null ) { var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = attribute.Id; if ( entity.AttributeValueDefaults != null && entity.AttributeValueDefaults.ContainsKey( attribute.Name ) ) { attributeValue.Value = entity.AttributeValueDefaults[attribute.Name]; } else { attributeValue.Value = attribute.DefaultValue; } attributeValues[attribute.Key] = attributeValue; } else { if ( !String.IsNullOrWhiteSpace( attribute.DefaultValue ) && String.IsNullOrWhiteSpace( attributeValues[attribute.Key].Value ) ) { attributeValues[attribute.Key].Value = attribute.DefaultValue; } } } } entity.Attributes = new Dictionary<string, Web.Cache.AttributeCache>(); allAttributes.ForEach( a => entity.Attributes.AddOrIgnore( a.Key, a ) ); entity.AttributeValues = attributeValues; } }
/// <summary> /// Gets the edit values. /// </summary> /// <param name="parentControl">The parent control.</param> /// <param name="item">The item.</param> public static void GetEditValues( Control parentControl, IHasAttributes item ) { if ( item.Attributes != null ) { foreach ( var attribute in item.Attributes ) { Control control = parentControl.FindControl( string.Format( "attribute_field_{0}", attribute.Value.Id ) ); if ( control != null ) { var value = new AttributeValueCache(); // Creating a brand new AttributeValue and setting its Value property. // The Value prop's setter then queries the AttributeCache passing in the AttributeId, which is 0 // The AttributeCache.Read method returns null value.Value = attribute.Value.FieldType.Field.GetEditValue( control, attribute.Value.QualifierValues ); item.AttributeValues[attribute.Key] = value; } } } }
/// <summary> /// Copies the attributes from one entity to another /// </summary> /// <param name="source">The source.</param> /// <param name="target">The target.</param> public static void CopyAttributes( IHasAttributes source, IHasAttributes target ) { if ( source != null && target != null ) { // Copy Attributes if ( source.Attributes != null ) { target.Attributes = new Dictionary<string, Web.Cache.AttributeCache>(); foreach ( var item in source.Attributes ) { target.Attributes.Add( item.Key, item.Value ); } } else { target.Attributes = null; } // Copy Attribute Values if ( source.AttributeValues != null ) { target.AttributeValues = new Dictionary<string, AttributeValueCache>(); foreach ( var item in source.AttributeValues ) { var value = item.Value; if ( value != null ) { var attributeValue = new AttributeValueCache(); attributeValue.AttributeId = value.AttributeId; attributeValue.Value = value.Value; target.AttributeValues.Add( item.Key, attributeValue ); } else { target.AttributeValues.Add( item.Key, null ); } } } else { target.AttributeValues = null; } } }