public IPublishedElement ConvertToElement(BlockItemData data, PropertyCacheLevel referenceCacheLevel, bool preview) { var publishedContentType = GetContentType(data.ContentTypeKey); // Only convert element types if (publishedContentType == null || publishedContentType.IsElement == false) { return(null); } var propertyValues = data.RawPropertyValues; // Get the UDI from the deserialized object. If this is empty, we can fallback to checking the 'key' if there is one var key = (data.Udi is GuidUdi gudi) ? gudi.Guid : Guid.Empty; if (key == Guid.Empty && propertyValues.TryGetValue("key", out var keyo)) { Guid.TryParse(keyo.ToString(), out key); } IPublishedElement element = new PublishedElement(publishedContentType, key, propertyValues, preview, referenceCacheLevel, _publishedSnapshotAccessor); element = _publishedModelFactory.CreateModel(element); return(element); }
public IPublishedElement ConvertToElement( BlockItemData data, PropertyCacheLevel referenceCacheLevel, bool preview) { // hack! we need to cast, we have no choice beacuse we cannot make breaking changes. var publishedContentCache = _publishedSnapshotAccessor.PublishedSnapshot.Content as IPublishedContentCache2; if (publishedContentCache == null) { throw new InvalidOperationException("The published content cache is not " + typeof(IPublishedContentCache2)); } // only convert element types - content types will cause an exception when PublishedModelFactory creates the model var publishedContentType = publishedContentCache.GetContentType(data.ContentTypeKey); if (publishedContentType == null || publishedContentType.IsElement == false) { return(null); } var propertyValues = data.RawPropertyValues; // Get the udi from the deserialized object. If this is empty we can fallback to checking the 'key' if there is one var key = (data.Udi is GuidUdi gudi) ? gudi.Guid : Guid.Empty; if (propertyValues.TryGetValue("key", out var keyo)) { Guid.TryParse(keyo.ToString(), out key); } IPublishedElement element = new PublishedElement(publishedContentType, key, propertyValues, preview, referenceCacheLevel, _publishedSnapshotAccessor); element = _publishedModelFactory.CreateModel(element); return(element); }
/// <summary> /// Creates a strongly typed published content model for an internal published content. /// </summary> /// <param name="content">The internal published content.</param> /// <returns>The strongly typed published content model.</returns> public static IPublishedContent CreateModel(this IPublishedContent content, IPublishedModelFactory publishedModelFactory) { if (publishedModelFactory == null) { throw new ArgumentNullException(nameof(publishedModelFactory)); } if (content == null) { return(null); } // get model // if factory returns nothing, throw var model = publishedModelFactory.CreateModel(content); if (model == null) { throw new InvalidOperationException("Factory returned null."); } // if factory returns a different type, throw if (!(model is IPublishedContent publishedContent)) { throw new InvalidOperationException($"Factory returned model of type {model.GetType().FullName} which does not implement IPublishedContent."); } return(publishedContent); }
public IPublishedElement?ConvertToElement(BlockItemData data, PropertyCacheLevel referenceCacheLevel, bool preview) { IPublishedContentCache?publishedContentCache = _publishedSnapshotAccessor.GetRequiredPublishedSnapshot().Content; // Only convert element types - content types will cause an exception when PublishedModelFactory creates the model IPublishedContentType?publishedContentType = publishedContentCache?.GetContentType(data.ContentTypeKey); if (publishedContentType == null || publishedContentType.IsElement == false) { return(null); } Dictionary <string, object?> propertyValues = data.RawPropertyValues; // Get the UDI from the deserialized object. If this is empty, we can fallback to checking the 'key' if there is one Guid key = data.Udi is GuidUdi gudi ? gudi.Guid : Guid.Empty; if (key == Guid.Empty && propertyValues.TryGetValue("key", out var keyo)) { Guid.TryParse(keyo !.ToString(), out key); } IPublishedElement element = new PublishedElement(publishedContentType, key, propertyValues, preview, referenceCacheLevel, _publishedSnapshotAccessor); element = _publishedModelFactory.CreateModel(element); return(element); }
public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview) { if (inter is IEnumerable <ContentBlock> items) { var elements = new List <IPublishedElement>(); foreach (var item in items) { if (item == null || item.ElementType.Equals(Guid.Empty)) { continue; } // NOTE: [LK:2019-09-03] Why `IPublishedCache` doesn't support Guids or UDIs, I do not know!? // Thought v8 was meant to be "GUID ALL THE THINGS!!1"? ¯\_(ツ)_/¯ if (ContentTypeCacheHelper.TryGetAlias(item.ElementType, out var alias, _contentTypeService) == false) { continue; } var contentType = _publishedSnapshotAccessor.PublishedSnapshot.Content.GetContentType(alias); if (contentType == null || contentType.IsElement == false) { continue; } var properties = new List <IPublishedProperty>(); foreach (var thing in item.Value) { var propType = contentType.GetPropertyType(thing.Key); if (propType != null) { properties.Add(new DetachedPublishedProperty(propType, owner, thing.Value, preview)); } } elements.Add(_publishedModelFactory.CreateModel(new DetachedPublishedElement(item.Key, contentType, properties))); } return(elements); } return(base.ConvertIntermediateToObject(owner, propertyType, referenceCacheLevel, inter, preview)); }
public virtual IPublishedElement[] ParseElements(IPublishedElement parent, JArray array) { if (array == null) { return(new IPublishedElement[0]); } List <IPublishedElement> items = new List <IPublishedElement>(); foreach (JObject item in array) { // Get basic information from the item Guid key = item.GetGuid("key"); string name = item.GetString("name"); Guid contentTypeKey = item.GetGuid("contentType"); // Get a reference to the content type IContentType contentType = _contentTypeService.Get(contentTypeKey); if (contentType == null) { _logger.Error(typeof(PublishedElementHelper), "Content type with key " + contentTypeKey + " not found."); continue; } // Convert the content type to it's published counterpart IPublishedContentType pct = _publishedContentTypeFactory.CreateContentType(contentType); // Initialize a new collection of properties List <IPublishedProperty> properties = new List <IPublishedProperty>(); // Create the model based on our implementation of IPublishedElement IPublishedElement element = new SkybrudPublishedElement(parent, key, name, pct, properties); foreach (JProperty prop in item.GetObject("properties").Properties()) { // Get a reference to the property type IPublishedPropertyType type = pct.GetPropertyType(prop.Name); if (type == null) { //_logger.Error<PublishedElementHelper>("Property type for property with alias {Alias} not found.", prop.Name); continue; } // Get a reference to the property editor if (_propertyEditors.TryGet(type.EditorAlias, out IDataEditor propEditor) == false) { _logger.Error <PublishedElementHelper>("Property editor with alias {Alias} not found.", type.EditorAlias); continue; } #region Borrowed from Doc Type Grid Editor ContentPropertyData contentPropData = new ContentPropertyData(prop.Value, type.DataType.Configuration); object newValue = prop.Value == null ? null : propEditor.GetValueEditor().FromEditor(contentPropData, prop.Value); PropertyType propType2; try { propType2 = contentType.CompositionPropertyTypes.First(x => x.PropertyEditorAlias.InvariantEquals(type.DataType.EditorAlias)); } catch (Exception ex) { throw new ElementsException($"Unable to find property editor with alias: {type.DataType.EditorAlias} (" + type.DataType.Id + ")", ex); } Property prop2 = null; try { /* HACK: [LK:2016-04-01] When using the "Umbraco.Tags" property-editor, the converted DB value does * not match the datatypes underlying db-column type. So it throws a "Type validation failed" exception. * We feel that the Umbraco core isn't handling the Tags value correctly, as it should be the responsiblity * of the "Umbraco.Tags" property-editor to handle the value conversion into the correct type. * See: http://issues.umbraco.org/issue/U4-8279 */ prop2 = new Property(propType2); prop2.SetValue(newValue); } catch (Exception ex) { _logger.Error(typeof(PublishedElementHelper), ex, "Error creating Property object."); } if (prop2 != null) { string newValue2 = propEditor.GetValueEditor().ConvertDbToString(propType2, newValue, _dataTypeService); properties.Add(new SkybrudPublishedProperty(element, type, prop.Name, newValue2)); } #endregion } // Let the current model factory create a typed model to wrap our model if (_publishedModelFactory != null) { element = _publishedModelFactory.CreateModel(element); } items.Add(element); } return(items.ToArray()); }
public HttpResponseMessage GetPreviewMarkup([FromBody] JObject item, int elementIndex, Guid elementKey, int contentId) { var preview = true; var content = UmbracoContext.Content.GetById(true, contentId); if (content == null) { _logger.Debug <ContentBlocksApiController>($"Unable to retrieve content for ID '{contentId}', it is most likely a new unsaved page."); } var element = default(IPublishedElement); var block = item.ToObject <ContentBlock>(); if (block != null && block.ElementType.Equals(Guid.Empty) == false) { if (ContentTypeCacheHelper.TryGetAlias(block.ElementType, out var alias, Services.ContentTypeService) == true) { var contentType = UmbracoContext.PublishedSnapshot.Content.GetContentType(alias); if (contentType != null && contentType.IsElement == true) { var properties = new List <IPublishedProperty>(); foreach (var thing in block.Value) { var propType = contentType.GetPropertyType(thing.Key); if (propType != null) { properties.Add(new DetachedPublishedProperty(propType, null, thing.Value, preview)); } } element = _publishedModelFactory.CreateModel(new DetachedPublishedElement(block.Key, contentType, properties)); } } } var viewData = new System.Web.Mvc.ViewDataDictionary(element) { { nameof(content), content }, { nameof(element), element }, { nameof(elementIndex), elementIndex }, }; if (ContentTypeCacheHelper.TryGetIcon(content.ContentType.Alias, out var contentIcon, Services.ContentTypeService) == true) { viewData.Add(nameof(contentIcon), contentIcon); } if (ContentTypeCacheHelper.TryGetIcon(element.ContentType.Alias, out var elementIcon, Services.ContentTypeService) == true) { viewData.Add(nameof(elementIcon), elementIcon); } var markup = default(string); try { markup = ContentBlocksViewHelper.RenderPartial(element.ContentType.Alias, viewData); } catch (InvalidCastException icex) { // NOTE: This type of exception happens on a new (unsaved) page, when the context becomes the parent page, // and the preview view is strongly typed to the current page's model type. markup = "<p class=\"text-center mt4\">Unable to render the preview until the page has been saved.</p>"; _logger.Error <ContentBlocksApiController>(icex, "Error rendering preview view."); } catch (Exception ex) { markup = $"<pre class=\"error\"><code>{ex}</code></pre>"; _logger.Error <ContentBlocksApiController>(ex, "Error rendering preview view."); } return(Request.CreateResponse(HttpStatusCode.OK, new { elementKey, markup })); }
private IPublishedElement ConvertValue(string id, string contentTypeAlias, string dataJson) { var contentTypes = GetContentTypesByAlias(contentTypeAlias); var properties = new List <IPublishedProperty>(); // Convert all the properties var data = JsonConvert.DeserializeObject(dataJson); var propValues = ((JObject)data).ToObject <Dictionary <string, object> >(); foreach (var jProp in propValues) { var propType = contentTypes.PublishedContentType.GetPropertyType(jProp.Key); if (propType == null) { continue; } /* Because we never store the value in the database, we never run the property editors * "ConvertEditorToDb" method however the property editors will expect their value to * be in a "DB" state so to get round this, we run the "ConvertEditorToDb" here before * we go on to convert the value for the view. */ _dataEditors.TryGet(propType.EditorAlias, out var propEditor); var propPreValues = GetPreValuesCollectionByDataTypeId(propType.DataType.Id); var contentPropData = new ContentPropertyData(jProp.Value, propPreValues); var newValue = propEditor.GetValueEditor().FromEditor(contentPropData, jProp.Value); // Performing "ValueProcessing" if any ValueProcessor is configured for this Property Editor-alias. // TODO: Process values //var processorsCollection = Current.Factory.GetInstance<DocTypeGridEditorValueProcessorsCollection>(); //var processor = processorsCollection.FirstOrDefault(x => x.IsProcessorFor(propEditor.Alias)); //if (processor != null) //{ // newValue = processor.ProcessValue(newValue); //} /* Now that we have the DB stored value, we actually need to then convert it into its * XML serialized state as expected by the published property by calling ConvertDbToString */ var propType2 = contentTypes.ContentType.CompositionPropertyTypes.First(x => x.PropertyEditorAlias.InvariantEquals(propType.DataType.EditorAlias)); Property prop2 = null; try { /* HACK: [LK:2016-04-01] When using the "Umbraco.Tags" property-editor, the converted DB value does * not match the datatypes underlying db-column type. So it throws a "Type validation failed" exception. * We feel that the Umbraco core isn't handling the Tags value correctly, as it should be the responsiblity * of the "Umbraco.Tags" property-editor to handle the value conversion into the correct type. * See: http://issues.umbraco.org/issue/U4-8279 */ prop2 = new Property(propType2); prop2.SetValue(newValue); } catch (Exception ex) { _logger.LogError(new EventId(0), ex, "[DocTypeGridEditor] Error creating Property object."); } if (prop2 != null) { var newValue2 = propEditor.GetValueEditor().ConvertDbToString(propType2, newValue, _dataTypeService); properties.Add(new DetachedPublishedProperty(propType, newValue2)); } } // Manually parse out the special properties propValues.TryGetValue("name", out object nameObj); Guid.TryParse(id, out Guid key); // Get the current request node we are embedded in var pcr = _umbracoContext.UmbracoContext.PublishedRequest; var containerNode = pcr != null && pcr.HasPublishedContent() ? pcr.PublishedContent : null; // Create the model based on our implementation of IPublishedElement IPublishedElement content = new DetachedPublishedElement( key, contentTypes.PublishedContentType, properties.ToArray()); if (_publishedModelFactory != null) { // Let the current model factory create a typed model to wrap our model content = _publishedModelFactory.CreateModel(content); } return(content); }