public override bool ShouldRun(string view, GridValueControlModel cell) { try { if (cell == null || cell.Value == null) { return(false); } if (cell.Value is JValue) { return(false); } if (cell.Value.Type == JTokenType.Array) { return(false); } return(cell.Value["dtgeContentTypeAlias"] != null && cell.Value["value"] != null); } catch (Exception ex) { CourierLogHelper.Error <DocTypeGridEditorGridCellResolver>("Error reading grid cell value: ", ex); return(false); } }
public override void PackagingProperty(Item item, ContentProperty propertyData) { if (propertyData.Value != null) { var links = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); if (links != null) { foreach (dynamic link in links) { if (link.id != null) { var objectTypeId = link.isMedia != null ? UmbracoNodeObjectTypeIds.Media : UmbracoNodeObjectTypeIds.Document; var itemProviderId = link.isMedia != null ? ItemProviderIds.mediaItemProviderGuid : ItemProviderIds.documentItemProviderGuid; link.id = ExecutionContext.DatabasePersistence.GetUniqueId((int)link.id, objectTypeId); item.Dependencies.Add(link.id.ToString(), itemProviderId); } else if (link.isMedia != null) { try { var mediaId = ExecutionContext.DatabasePersistence.GetUniqueIdFromMediaFile(link.url); item.Dependencies.Add(mediaId.ToString(), ItemProviderIds.mediaItemProviderGuid); } catch (Exception e) { CourierLogHelper.Error <MultiUrlPickerDataResolverProvider>(string.Format("Error setting media-item dependency, name={0}, url={1}", link.name, link.url), e); } } } propertyData.Value = links.ToString(); } } }
public override void PackagingProperty(Item item, ContentProperty propertyData) { if (propertyData == null || propertyData.Value == null) { return; } JArray links; try { links = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); } catch (Exception ex) { CourierLogHelper.Error <MultiUrlPickerPropertyDataResolver>(String.Format("There was a problem deserializing RJP.MultiUrlPicker data: {0}", propertyData.Value.ToString()), ex); throw; } if (links == null) { return; } foreach (var link in links) { var isMedia = link["isMedia"] != null || link["udi"] != null && link["udi"].ToString().StartsWith("umb://media"); if (link["id"] != null || link["udi"] != null) { var objectTypeId = isMedia ? UmbracoNodeObjectTypeIds.Media : UmbracoNodeObjectTypeIds.Document; var itemProviderId = isMedia ? ItemProviderIds.mediaItemProviderGuid : ItemProviderIds.documentItemProviderGuid; var nodeGuid = Guid.Empty; if (link["udi"] != null) { var guidString = isMedia ? link["udi"].ToString().TrimStart("umb://media/") : link["udi"].ToString().TrimStart("umb://document/"); Guid.TryParse(guidString, out nodeGuid); } else if (link["id"] != null) { int linkIdTemp; if (int.TryParse(link["id"].ToString(), out linkIdTemp)) { nodeGuid = ExecutionContext.DatabasePersistence.GetUniqueId(linkIdTemp, objectTypeId); } } if (Guid.Empty.Equals(nodeGuid)) { continue; } var guid = nodeGuid.ToString(); item.Dependencies.Add(guid, itemProviderId); // only need to adjust this if it was an id converted to a guid. udis are already unique and match on both source and destination if (link["id"] != null) { link["id"] = guid; } } else if (isMedia && link["url"] != null) { try { var mediaId = ExecutionContext.DatabasePersistence.GetUniqueIdFromMediaFile(link["url"].ToString()); if (!Guid.Empty.Equals(mediaId)) { item.Dependencies.Add(mediaId.ToString(), ItemProviderIds.mediaItemProviderGuid); } } catch (Exception ex) { CourierLogHelper.Error <MultiUrlPickerPropertyDataResolver>(string.Format("Error setting media-item dependency, name={0}, url={1}", link["name"], link["url"]), ex); } } } propertyData.Value = links.ToString(); }
private void ProcessCell(Item item, ContentProperty propertyData, GridValueControlModel cell, Action direction) { var documentTypeAlias = cell.Value["dtgeContentTypeAlias"].ToString(); if (string.IsNullOrWhiteSpace(documentTypeAlias)) { return; } var documentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(documentTypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); var cellValueJson = cell.Value["value"].ToString(); if (string.IsNullOrWhiteSpace(cellValueJson)) { return; } var cellValue = JsonConvert.DeserializeObject(cellValueJson); if (!(cellValue is JObject)) { return; } var propertyValues = ((JObject)cellValue).ToObject <Dictionary <string, object> >(); if (direction == Action.Packaging) { item.Dependencies.Add(documentType.UniqueId.ToString(), ItemProviderIds.documentTypeItemProviderGuid); } // get the ItemProvider for the ResolutionManager var propertyDataItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); var properties = documentType.Properties; // check for compositions foreach (var masterDocumentTypeAlias in documentType.MasterDocumentTypes) { var masterDocumentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(masterDocumentTypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); if (masterDocumentType != null) { properties.AddRange(masterDocumentType.Properties); } } foreach (var property in properties) { object value = null; if (!propertyValues.TryGetValue(property.Alias, out value) || value == null) { continue; } var datatype = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>(new ItemIdentifier(property.DataTypeDefinitionId.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); // create a pseudo item for sending through resolvers var pseudoPropertyDataItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, EditorAlias, datatype.PropertyEditorAlias, property.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = property.Alias, DataType = datatype.UniqueID, PropertyEditorAlias = datatype.PropertyEditorAlias, Value = value } } }; if (direction == Action.Packaging) { try { // run the resolvers (convert Ids/integers into UniqueIds/guids) ResolutionManager.Instance.PackagingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <DocTypeGridEditorGridCellResolver>(string.Concat("Error packaging data value: ", pseudoPropertyDataItem.Name), ex); } // add in dependencies when packaging item.Dependencies.AddRange(pseudoPropertyDataItem.Dependencies); item.Resources.AddRange(pseudoPropertyDataItem.Resources); } else if (direction == Action.Extracting) { try { // run the resolvers (convert UniqueIds/guids back to Ids/integers) ResolutionManager.Instance.ExtractingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <DocTypeGridEditorGridCellResolver>( string.Concat("Error extracting data value: ", pseudoPropertyDataItem.Name), ex); } } if (pseudoPropertyDataItem.Data != null && pseudoPropertyDataItem.Data.Any()) { // get the first (and only) property of the pseudo item created above var firstProperty = pseudoPropertyDataItem.Data.FirstOrDefault(); if (firstProperty != null) { // replace the property value with the resolved value propertyValues[property.Alias] = firstProperty.Value; // (if packaging) add a dependency for the property's data-type if (direction == Action.Packaging) { item.Dependencies.Add(firstProperty.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } // build up json as a string first, as directly converting // propValues to a JToken causes json objects to be converted into a string // (such as nested content inside a doctypegrid) var jsonString = new StringBuilder("{"); foreach (var val in propertyValues) { jsonString.Append("\""); jsonString.Append(val.Key); jsonString.Append("\":"); // check if it's a json object and not just a string if (val.Value.ToString().Trim().StartsWith("[")) { jsonString.Append(val.Value); } else { jsonString.Append("\""); jsonString.Append(val.Value); jsonString.Append("\""); } jsonString.Append(","); } if (jsonString.Length > 1) { jsonString.Remove(jsonString.Length - 1, 1); } jsonString.Append("}"); var tempCellValue = JToken.Parse(jsonString.ToString()); cell.Value["value"] = tempCellValue; }
private void ProcessCell(Item item, ContentProperty propertyData, GridValueControlModel cell, Action direction) { var documentTypeAlias = cell.Value["dtgeContentTypeAlias"].ToString(); if (string.IsNullOrWhiteSpace(documentTypeAlias)) { return; } var documentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(documentTypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); var cellValueJson = cell.Value["value"].ToString(); if (string.IsNullOrWhiteSpace(cellValueJson)) { return; } var cellValue = JsonConvert.DeserializeObject(cellValueJson); if (!(cellValue is JObject)) { return; } var propertyValues = ((JObject)cellValue).ToObject <Dictionary <string, object> >(); //this editor can contain references to doctypes that no longer exist //then it would be pointless to iterate over properties, they can't be set anyway if (documentType != null) { if (direction == Action.Packaging) { item.Dependencies.Add(documentType.UniqueId.ToString(), ItemProviderIds.documentTypeItemProviderGuid); } // get the ItemProvider for the ResolutionManager var propertyDataItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); var properties = documentType.Properties; // check for compositions foreach (var masterDocumentTypeAlias in documentType.MasterDocumentTypes) { var masterDocumentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(masterDocumentTypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); if (masterDocumentType != null) { properties.AddRange(masterDocumentType.Properties); } } foreach (var property in properties) { object value = null; if (!propertyValues.TryGetValue(property.Alias, out value) || value == null) { continue; } var datatype = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>(new ItemIdentifier(property.DataTypeDefinitionId.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); // create a pseudo item for sending through resolvers var pseudoPropertyDataItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, EditorAlias, datatype.PropertyEditorAlias, property.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = property.Alias, DataType = datatype.UniqueID, PropertyEditorAlias = datatype.PropertyEditorAlias, Value = value } } }; if (direction == Action.Packaging) { try { // run the resolvers (convert Ids/integers into UniqueIds/guids) ResolutionManager.Instance.PackagingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <DocTypeGridEditorGridCellResolver>(string.Concat("Error packaging data value: ", pseudoPropertyDataItem.Name), ex); } // add in dependencies when packaging item.Dependencies.AddRange(pseudoPropertyDataItem.Dependencies); item.Resources.AddRange(pseudoPropertyDataItem.Resources); } else if (direction == Action.Extracting) { try { // run the resolvers (convert UniqueIds/guids back to Ids/integers) ResolutionManager.Instance.ExtractingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <DocTypeGridEditorGridCellResolver>( string.Concat("Error extracting data value: ", pseudoPropertyDataItem.Name), ex); } } if (pseudoPropertyDataItem.Data != null && pseudoPropertyDataItem.Data.Any()) { // get the first (and only) property of the pseudo item created above var firstProperty = pseudoPropertyDataItem.Data.FirstOrDefault(); if (firstProperty != null) { // get the resolved value var resolvedValue = firstProperty.Value; if (direction == Action.Extracting && resolvedValue is string && resolvedValue.ToString().DetectIsJson()) { // because the DTGE data must be a JSON object type, we'll want to deserialize any encoded strings propertyValues[property.Alias] = JsonConvert.DeserializeObject(resolvedValue.ToString()); } else { // replace the property value with the resolved value propertyValues[property.Alias] = resolvedValue; } // (if packaging) add a dependency for the property's data-type if (direction == Action.Packaging) { item.Dependencies.Add(firstProperty.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } } // the value assigned back must be a JSON object type cell.Value["value"] = JObject.FromObject(propertyValues); }
/// <summary> /// Processes the property data. /// This method is used both for packaging and extracting property data. /// We want to deserialize the property data and then run it through the ResolutionManager for either packaging or extracting. /// This is done by creating a pseudo item immitating a property data item and having the ResolutionManager use its normal resolvers for resolving and finding dependencies. /// If we are packaging we also add any found dependencies and resources to the item which the property data belongs to. /// </summary> /// <param name="item">Item being handled</param> /// <param name="propertyData">Nested Content property being handled</param> /// <param name="action">Indicates if we are packaging or extracting the item/property</param> private void ProcessPropertyData(Item item, ContentProperty propertyData, Action action) { // add a dependency to the dataType if packaging if (action == Action.Packaging) { item.Dependencies.Add(propertyData.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } // deserialize the Nested Content value into an array of Nested Content items var nestedContentItems = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); // get the ItemProvider for the ResolutionManager var propertyDataItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); // loop through all the Nested Content items if (nestedContentItems != null && nestedContentItems.Any()) { foreach (var nestedContentItem in nestedContentItems) { // get the document type for the item, if it can't be found, skip to the next item var documentTypeAlias = nestedContentItem["ncContentTypeAlias"]; if (documentTypeAlias == null) { continue; } var documentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(documentTypeAlias.ToString(), ItemProviderIds.documentTypeItemProviderGuid)); if (documentType == null) { continue; } // get the properties available on the document type var properties = documentType.Properties; // add in properties from all composition document types, as these are not located on the document type itself foreach (var masterDocumentTypeAlias in documentType.MasterDocumentTypes) { var masterDocumentType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(masterDocumentTypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); if (masterDocumentType != null) { properties.AddRange(masterDocumentType.Properties); } } // run through all properties, creating pseudo items and sending them through the resolvers foreach (var property in properties) { var value = nestedContentItem[property.Alias]; if (value != null) { var dataType = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>(new ItemIdentifier(property.DataTypeDefinitionId.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); var pseudoPropertyDataItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, propertyData.PropertyEditorAlias, dataType.PropertyEditorAlias, property.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = property.Alias, DataType = dataType.UniqueID, PropertyEditorAlias = dataType.PropertyEditorAlias, Value = value.ToString() } } }; if (action == Action.Packaging) { try { // run the resolvers (convert Ids/integers into UniqueIds/guids) ResolutionManager.Instance.PackagingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentPropertyDataResolver>(string.Concat("Error packaging data value: ", pseudoPropertyDataItem.Name), ex); } // add in dependencies when packaging item.Dependencies.AddRange(pseudoPropertyDataItem.Dependencies); item.Resources.AddRange(pseudoPropertyDataItem.Resources); } else { try { // run the resolvers (convert UniqueIds/guids back to Ids/integers) ResolutionManager.Instance.ExtractingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentPropertyDataResolver>(string.Concat("Error extracting data value: ", pseudoPropertyDataItem.Name), ex); } } if (pseudoPropertyDataItem.Data != null && pseudoPropertyDataItem.Data.Any()) { // get the first (and only) property of the pseudo item created above var firstProperty = pseudoPropertyDataItem.Data.FirstOrDefault(); if (firstProperty != null) { // serialize the value of the property var serializedValue = firstProperty.Value as string ?? JsonConvert.SerializeObject(firstProperty.Value); // replace the values on the Nested Content item property with the resolved values nestedContentItem[property.Alias] = new JValue(serializedValue); // if packaging - add a dependency for the property's data-type if (action == Action.Packaging) { item.Dependencies.Add(firstProperty.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } } } // serialize the whole vorto property back to json and save the value on the property data propertyData.Value = JsonConvert.SerializeObject(nestedContentItems); } }
private void ResolvePropertyData(Item item, ContentProperty propertyData, Direction direction) { if (propertyData == null || propertyData.Value == null) { return; } // create a fake `PublishedPropertyType` var dataTypeId = ExecutionContext.DatabasePersistence.GetNodeId(propertyData.DataType, NodeObjectTypes.DataType); // deserialize the current Property's value into a 'MortarValue' var mortarValue = JsonConvert.DeserializeObject <MortarValue>(propertyData.Value.ToString()); // get the `PropertyItemProvider` from the collection. var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ProviderIDCollection.propertyDataItemProviderGuid, this.ExecutionContext); if (mortarValue != null) { foreach (var mortarBlock in mortarValue) { foreach (var mortarRow in mortarBlock.Value) { var rowOptionsDocTypeAlias = MortarHelper.GetRowOptionsDocType(dataTypeId, mortarBlock.Key); if (!string.IsNullOrWhiteSpace(rowOptionsDocTypeAlias)) { mortarRow.RawOptions = ResolveMultiplePropertyItemData(item, propertyItemProvider, mortarRow.RawOptions, rowOptionsDocTypeAlias, direction); } foreach (var mortarItem in mortarRow.Items) { if (mortarItem == null) { CourierLogHelper.Warn <MortarDataResolver>("MortarItem appears to be null, (from '{0}' block)", () => mortarBlock.Key); continue; } if (mortarItem.Type == null) { CourierLogHelper.Warn <MortarDataResolver>("MortarItem did not contain a value for Type, (from '{0}' block)", () => mortarBlock.Key); continue; } switch (mortarItem.Type.ToUpperInvariant()) { case "DOCTYPE": // resolve the doctype alias/guid string docTypeAlias = string.Empty; if (mortarItem.AdditionalInfo.ContainsKey("docType")) { docTypeAlias = mortarItem.AdditionalInfo["docType"]; DocumentType docType; Guid docTypeGuid; if (Guid.TryParse(docTypeAlias, out docTypeGuid)) { docType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>( new ItemIdentifier(docTypeGuid.ToString(), ProviderIDCollection.documentTypeItemProviderGuid)); docTypeAlias = docType.Alias; } else { docType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>( new ItemIdentifier(docTypeAlias, ProviderIDCollection.documentTypeItemProviderGuid)); docTypeGuid = docType.UniqueId; } if (direction == Direction.Packaging) { mortarItem.AdditionalInfo["docType"] = docTypeAlias; // add dependency for the DocType var name = string.Concat("Document type: ", docTypeAlias); var dependency = new Dependency(name, docTypeAlias, ProviderIDCollection.documentTypeItemProviderGuid); item.Dependencies.Add(dependency); } else if (direction == Direction.Extracting) { mortarItem.AdditionalInfo["docType"] = docTypeGuid.ToString(); } } // resolve the value's properties mortarItem.RawValue = ResolveMultiplePropertyItemData(item, propertyItemProvider, mortarItem.RawValue, docTypeAlias, direction); break; case "EMBED": // we don't need Courier to process the embed code - it's pure HTML break; case "LINK": mortarItem.RawValue = ConvertIdentifier(mortarItem.RawValue, item, direction, ProviderIDCollection.documentItemProviderGuid, "Document"); break; case "MEDIA": mortarItem.RawValue = ConvertIdentifier(mortarItem.RawValue, item, direction, ProviderIDCollection.mediaItemProviderGuid, "Media"); break; case "RICHTEXT": //From the 'MortarValueConverter' it appears that the DocumentTypeAlias, PropertyEditorAlias and PropertyTypeAlias are //all constants, so we reuse them here. mortarItem.RawValue = ResolvePropertyItemData(item, propertyItemProvider, mortarItem.RawValue, Constants.PropertyEditors.TinyMCEAlias, "bodyText", Guid.Empty, direction); break; default: break; } } } } propertyData.Value = JsonConvert.SerializeObject(mortarValue); } }
private object ResolvePropertyItemData(Item item, ItemProvider itemProvider, object value, string propertyEditorAlias, string propertyTypeAlias, Guid dataTypeGuid, Direction direction = Direction.Packaging) { // create a 'fake' item for Courier to process var fakeItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: {2} ({3})]", item.Name, EditorAlias, propertyEditorAlias, propertyTypeAlias), Data = new List <ContentProperty> { new ContentProperty { Alias = propertyTypeAlias, DataType = dataTypeGuid, PropertyEditorAlias = propertyEditorAlias, Value = value } } }; if (direction == Direction.Packaging) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.PackagingItem(fakeItem, itemProvider); } catch (Exception ex) { CourierLogHelper.Error <MortarDataResolver>(string.Concat("Error packaging data value: ", fakeItem.Name), ex); } // pass up the dependencies if (fakeItem.Dependencies != null && fakeItem.Dependencies.Count > 0) { item.Dependencies.AddRange(fakeItem.Dependencies); } // pass up the resources if (fakeItem.Resources != null && fakeItem.Resources.Count > 0) { item.Resources.AddRange(fakeItem.Resources); } } else if (direction == Direction.Extracting) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.ExtractingItem(fakeItem, itemProvider); item.Status = ItemStatus.NeedPostProcessing; item.PostProcess = true; } catch (Exception ex) { CourierLogHelper.Error <MortarDataResolver>(string.Concat("Error extracting data value: ", fakeItem.Name), ex); } } // return the resolved data from the 'fake' item if (fakeItem.Data != null && fakeItem.Data.Any()) { return(fakeItem.Data.FirstOrDefault().Value); } return(value); }
private void ProcessCell(Item item, ContentProperty propertyData, dynamic cell, Direction direction) { string docTypeId = cell?.value?.docType?.ToString(); string cellValue = cell?.value?.value?.ToString(); if (cellValue == null || docTypeId == null) { return; } var data = JsonConvert.DeserializeObject(cellValue); if (!(data is JObject)) { return; } var propValues = ((JObject)data).ToObject <Dictionary <string, object> >(); var docType = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>( new ItemIdentifier(docTypeId, ItemProviderIds.documentTypeItemProviderGuid)); if (direction == Direction.Packaging) { item.Dependencies.Add(docTypeId, ItemProviderIds.documentTypeItemProviderGuid); //package doctype from guid to alias cell.value.docType = new JValue(docType.Alias); } else if (direction == Direction.Extracting) { //extract doctype from alias to guid cell.value.docType = new JValue(docType.UniqueId.ToString()); } var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); foreach (var prop in docType.Properties) { object value; if (!propValues.TryGetValue(prop.Alias, out value)) { continue; } var datatype = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>( new ItemIdentifier( prop.DataTypeDefinitionId.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); var fakeItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, EditorAlias, datatype.PropertyEditorAlias, prop.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = prop.Alias, DataType = datatype.UniqueID, PropertyEditorAlias = datatype.PropertyEditorAlias, Value = value.ToString() } } }; if (direction == Direction.Packaging) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.PackagingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentDataResolverProvider>( string.Concat("Error packaging data value: ", fakeItem.Name), ex); } } else if (direction == Direction.Extracting) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.ExtractingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentDataResolverProvider>( string.Concat("Error extracting data value: ", fakeItem.Name), ex); } } // pass up the dependencies and resources item.Dependencies.AddRange(fakeItem.Dependencies); item.Resources.AddRange(fakeItem.Resources); if (fakeItem.Data != null && fakeItem.Data.Any()) { var firstDataType = fakeItem.Data.FirstOrDefault(); if (firstDataType != null) { // set the resolved property data value string serializedValue = firstDataType.Value as string ?? JsonConvert.SerializeObject(firstDataType.Value); object jsonValue; try { jsonValue = JsonConvert.DeserializeObject(serializedValue); } catch { jsonValue = serializedValue; } propValues[prop.Alias] = jsonValue; // (if packaging) add a dependency for the property's data-type if (direction == Direction.Packaging) { item.Dependencies.Add(firstDataType.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } var serialized = JsonConvert.SerializeObject(propValues); cell.value.value = JsonConvert.DeserializeObject(serialized); }
/// <summary> /// Replaces the property data Ids. /// </summary> /// <param name="item">The item.</param> /// <param name="propertyData">The property data.</param> /// <param name="direction">The direction.</param> private void ReplacePropertyDataIds(Item item, ContentProperty propertyData, Direction direction) { if (propertyData != null && propertyData.Value != null) { var dataType = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>(new ItemIdentifier(propertyData.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); //Fetch the Prevalues for the current Property's DataType (if its an 'Archetype config') var prevalue = dataType.Prevalues.FirstOrDefault(x => x.Alias.ToLowerInvariant().Equals("archetypeconfig")); var archetypePreValue = prevalue == null ? null : JsonConvert.DeserializeObject <ArchetypePreValue>(prevalue.Value, ArchetypeHelper.Instance.JsonSerializerSettings); RetrieveAdditionalProperties(ref archetypePreValue); //Deserialize the value of the current Property to an ArchetypeModel and set additional properties before converting values var sourceJson = propertyData.Value.ToString(); var archetype = JsonConvert.DeserializeObject <ArchetypeModel>(sourceJson, ArchetypeHelper.Instance.JsonSerializerSettings); RetrieveAdditionalProperties(ref archetype, archetypePreValue); if (archetype != null) { // get the `PropertyItemProvider` from the collection. var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); foreach (var property in archetype.Fieldsets.SelectMany(x => x.Properties)) { if (property == null || string.IsNullOrWhiteSpace(property.PropertyEditorAlias)) { continue; } // create a 'fake' item for Courier to process var fakeItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", new[] { item.Name, EditorAlias, property.PropertyEditorAlias, property.Alias }), Data = new List <ContentProperty> { new ContentProperty { Alias = property.Alias, DataType = ExecutionContext.DatabasePersistence.GetUniqueId(property.DataTypeId, UmbracoNodeObjectTypeIds.DataType), PropertyEditorAlias = property.PropertyEditorAlias, Value = property.Value } } }; if (direction == Direction.Packaging) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.PackagingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <ArchetypeDataResolver>(string.Concat("Error packaging data value: ", fakeItem.Name), ex); } // pass up the dependencies and resources item.Dependencies.AddRange(fakeItem.Dependencies); item.Resources.AddRange(fakeItem.Resources); } else if (direction == Direction.Extracting) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.ExtractingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <ArchetypeDataResolver>(string.Concat("Error extracting data value: ", fakeItem.Name), ex); } } if (fakeItem.Data != null && fakeItem.Data.Any()) { var firstDataType = fakeItem.Data.FirstOrDefault(); if (firstDataType != null) { // set the resolved property data value property.Value = firstDataType.Value; // (if packaging) add a dependency for the property's data-type if (direction == Direction.Packaging) { item.Dependencies.Add(firstDataType.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } // serialize the Archetype back to a string propertyData.Value = archetype.SerializeForPersistence(); } } }
/// <summary> /// Processes the property data. /// This method is used both for packaging and extracting property data. /// We want to deserialize the property data and then run it through the ResolutionManager for either packaging or extracting. /// This is done by creating a pseudo item immitating a property data item and having the ResolutionManager use its normal resolvers for resolving and finding dependencies. /// If we are packaging we also add any found dependencies and resources to the item which the property data belongs to. /// </summary> /// <param name="item">Item being handled</param> /// <param name="propertyData">Nested Content property being handled</param> /// <param name="action">Indicates if we are packaging or extracting the item/property</param> private void ProcessPropertyData(Item item, ContentProperty propertyData, Action action) { // add a dependency to the dataType if packaging if (action == Action.Packaging) { item.Dependencies.Add(propertyData.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } // deserialize the Nested Content value into an array of Nested Content items var nestedContentItems = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); // get the ItemProvider for the ResolutionManager var propertyDataItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); // loop through all the Nested Content items if (nestedContentItems != null) { var resolvedDocTypes = new Dictionary <string, DocumentType>(); var resolvedDataTypes = new Dictionary <string, DataType>(); var items = new List <Dictionary <string, object> >(); foreach (var nestedContentItem in nestedContentItems) { // get the document type for the item, if it can't be found, skip to the next item var documentTypeAlias = nestedContentItem["ncContentTypeAlias"]; if (documentTypeAlias == null) { continue; } var documentTypeAliasString = documentTypeAlias.ToString(); var documentType = GetDocumentType(documentTypeAliasString, resolvedDocTypes); if (documentType == null) { continue; } // get the properties available on the document type var properties = documentType.Properties; // add in properties from all composition document types, as these are not located on the document type itself foreach (var masterDocumentTypeAlias in documentType.MasterDocumentTypes) { var masterDocumentType = GetDocumentType(masterDocumentTypeAlias, resolvedDocTypes); if (masterDocumentType != null) { properties.AddRange(masterDocumentType.Properties); } } var propertyValues = nestedContentItem.ToObject <Dictionary <string, object> >(); // run through all properties, creating pseudo items and sending them through the resolvers foreach (var property in properties) { object value = null; if (!propertyValues.TryGetValue(property.Alias, out value) || value == null) { continue; } var dataType = GetDataType(property.DataTypeDefinitionId.ToString(), resolvedDataTypes); var pseudoPropertyDataItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, propertyData.PropertyEditorAlias, dataType.PropertyEditorAlias, property.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = property.Alias, DataType = dataType.UniqueID, PropertyEditorAlias = dataType.PropertyEditorAlias, Value = value } } }; if (action == Action.Packaging) { try { // run the resolvers (convert Ids/integers into UniqueIds/guids) ResolutionManager.Instance.PackagingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentPropertyDataResolver>(string.Concat("Error packaging data value: ", pseudoPropertyDataItem.Name), ex); } // add in dependencies when packaging item.Dependencies.AddRange(pseudoPropertyDataItem.Dependencies); item.Resources.AddRange(pseudoPropertyDataItem.Resources); } else { try { // run the resolvers (convert UniqueIds/guids back to Ids/integers) ResolutionManager.Instance.ExtractingItem(pseudoPropertyDataItem, propertyDataItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentPropertyDataResolver>(string.Concat("Error extracting data value: ", pseudoPropertyDataItem.Name), ex); } } if (pseudoPropertyDataItem.Data != null && pseudoPropertyDataItem.Data.Count > 0) { // get the first (and only) property of the pseudo item created above var firstProperty = pseudoPropertyDataItem.Data.Count > 0 ? pseudoPropertyDataItem.Data[0] : null; if (firstProperty != null) { // get the resolved value var resolvedValue = firstProperty.Value; if (action == Action.Extracting && resolvedValue is string && resolvedValue.ToString().DetectIsJson()) { // because the nested-content data must be a JSON object type, we'll want to deserialize any encoded strings propertyValues[property.Alias] = JsonConvert.DeserializeObject(resolvedValue.ToString()); } else { // replace the property value with the resolved value propertyValues[property.Alias] = resolvedValue; } // if packaging - add a dependency for the property's data-type if (action == Action.Packaging) { item.Dependencies.Add(firstProperty.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } items.Add(propertyValues); } // serialize the whole nested-content property back to JSON and save the value on the property data propertyData.Value = JsonConvert.SerializeObject(items); } }
public override void PackagingProperty(Item item, ContentProperty propertyData) { if (propertyData == null || propertyData.Value == null) { return; } var links = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); if (links == null) { return; } foreach (var link in links) { var isMedia = link["isMedia"] != null; if (link["id"] != null) { var objectTypeId = isMedia ? UmbracoNodeObjectTypeIds.Media : UmbracoNodeObjectTypeIds.Document; var itemProviderId = isMedia ? ItemProviderIds.mediaItemProviderGuid : ItemProviderIds.documentItemProviderGuid; int linkId; var nodeGuid = int.TryParse(link["id"].ToString(), out linkId) ? ExecutionContext.DatabasePersistence.GetUniqueId(linkId, objectTypeId) : Guid.Empty; if (Guid.Empty.Equals(nodeGuid)) { continue; } var guid = nodeGuid.ToString(); item.Dependencies.Add(guid, itemProviderId); link["id"] = guid; } else if (isMedia && link["url"] != null) { try { var mediaId = ExecutionContext.DatabasePersistence.GetUniqueIdFromMediaFile(link["url"].ToString()); if (!Guid.Empty.Equals(mediaId)) { item.Dependencies.Add(mediaId.ToString(), ItemProviderIds.mediaItemProviderGuid); } } catch (Exception ex) { CourierLogHelper.Error <MultiUrlPickerPropertyDataResolver>(string.Format("Error setting media-item dependency, name={0}, url={1}", link["name"], link["url"]), ex); } } } propertyData.Value = links.ToString(); }
private void ProcessItemPropertyData(Item item, ContentTypeProperty propertyType, JToken innerContentItem, ItemProvider propertyItemProvider, Action action, Dictionary <string, DataType> resolvedDataTypes) { var value = innerContentItem[propertyType.Alias]; if (value != null) { var dataType = GetDataType(propertyType.DataTypeDefinitionId.ToString(), resolvedDataTypes); // create a 'fake' item for Courier to process var pseudoPropertyDataItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Inner {2} ({3})]", item.Name, this.EditorAlias, dataType.PropertyEditorAlias, propertyType.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = propertyType.Alias, DataType = dataType.UniqueID, PropertyEditorAlias = dataType.PropertyEditorAlias, Value = value.ToString() } } }; if (action == Action.Packaging) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.PackagingItem(pseudoPropertyDataItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <InnerContentPropertyDataResolver>(string.Concat("Error packaging data value: ", pseudoPropertyDataItem.Name), ex); } } else if (action == Action.Extracting) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.ExtractingItem(pseudoPropertyDataItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <InnerContentPropertyDataResolver>(string.Concat("Error extracting data value: ", pseudoPropertyDataItem.Name), ex); } } // pass up the dependencies and resources item.Dependencies.AddRange(pseudoPropertyDataItem.Dependencies); item.Resources.AddRange(pseudoPropertyDataItem.Resources); if (pseudoPropertyDataItem.Data != null && pseudoPropertyDataItem.Data.Any()) { // get the first (and only) property of the pseudo item created above var firstProperty = pseudoPropertyDataItem.Data.FirstOrDefault(); if (firstProperty != null) { // serialize the value of the property var serializedValue = firstProperty.Value as string ?? JsonConvert.SerializeObject(firstProperty.Value); // replace the values on the Inner Content item property with the resolved values innerContentItem[propertyType.Alias] = new JValue(serializedValue); // if packaging - add a dependency for the property's data-type if (action == Action.Packaging) { item.Dependencies.Add(firstProperty.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } }
private void ProcessProperty(Item item, ContentProperty propertyData, Direction direction) { var propertyItemProvider = ItemProviderCollection.Instance.GetProvider(ItemProviderIds.propertyDataItemProviderGuid, ExecutionContext); if (direction == Direction.Packaging) { item.Dependencies.Add(propertyData.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } var array = JsonConvert.DeserializeObject <JArray>(propertyData.Value.ToString()); foreach (var ncObj in array) { var doctypeAlias = ncObj["ncContentTypeAlias"].ToString(); var doctype = ExecutionContext.DatabasePersistence.RetrieveItem <DocumentType>(new ItemIdentifier(doctypeAlias, ItemProviderIds.documentTypeItemProviderGuid)); if (doctype == null) { continue; } foreach (var propertyType in doctype.Properties) { object o; if ((o = ncObj[propertyType.Alias]) != null) { //make fake item var value = o.ToString(); var datatype = ExecutionContext.DatabasePersistence.RetrieveItem <DataType>( new ItemIdentifier(propertyType.DataTypeDefinitionId.ToString(), ItemProviderIds.dataTypeItemProviderGuid)); var fakeItem = new ContentPropertyData { ItemId = item.ItemId, Name = string.Format("{0} [{1}: Nested {2} ({3})]", item.Name, EditorAlias, datatype.PropertyEditorAlias, propertyType.Alias), Data = new List <ContentProperty> { new ContentProperty { Alias = propertyType.Alias, DataType = datatype.UniqueID, PropertyEditorAlias = datatype.PropertyEditorAlias, Value = value } } }; if (direction == Direction.Packaging) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.PackagingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentDataResolverProvider>( string.Concat("Error packaging data value: ", fakeItem.Name), ex); } } else if (direction == Direction.Extracting) { try { // run the 'fake' item through Courier's data resolvers ResolutionManager.Instance.ExtractingItem(fakeItem, propertyItemProvider); } catch (Exception ex) { CourierLogHelper.Error <NestedContentDataResolverProvider>( string.Concat("Error extracting data value: ", fakeItem.Name), ex); } } // pass up the dependencies and resources item.Dependencies.AddRange(fakeItem.Dependencies); item.Resources.AddRange(fakeItem.Resources); if (fakeItem.Data != null && fakeItem.Data.Any()) { var firstDataType = fakeItem.Data.FirstOrDefault(); if (firstDataType != null) { // set the resolved property data value string serializedValue = firstDataType.Value as string ?? JsonConvert.SerializeObject(firstDataType.Value); ncObj[propertyType.Alias] = new JValue(serializedValue); // (if packaging) add a dependency for the property's data-type if (direction == Direction.Packaging) { item.Dependencies.Add(firstDataType.DataType.ToString(), ItemProviderIds.dataTypeItemProviderGuid); } } } } } } propertyData.Value = JsonConvert.SerializeObject(array); }