Exemple #1
0
        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);
        }
Exemple #2
0
        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);
        }
Exemple #3
0
        /// <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);
        }
Exemple #4
0
    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);
    }
Exemple #5
0
        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));
        }
Exemple #6
0
        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());
        }
Exemple #7
0
        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 }));
        }
Exemple #8
0
        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);
        }