/// <summary>
    ///     Creates a strongly typed published content model for an internal published content.
    /// </summary>
    /// <param name="content">The internal published content.</param>
    /// <param name="publishedModelFactory">The published model factory</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
        IPublishedElement 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 static IPosConImageItem PosConPartialForImage(this HtmlHelper helper, IPublishedElement publishedElement)
        {
            var posConItems = DependencyResolver.Current.GetServices <IPosConImageItem>();

            var item = posConItems
                       .Cast <IPosConImageItem>()
                       .Where(x => x.ModelType == publishedElement.GetType())
                       .FirstOrDefault();

            if (item != null)
            {
                return(item);
            }
            else
            {
                posConItems = DependencyResolver.Current.GetService <IPosConImageItemInternal[]>();

                return(posConItems
                       .Where(x => x.ModelType == publishedElement.GetType())
                       .Cast <IPosConImageItem>()
                       .FirstOrDefault());
            }
        }
Exemple #3
0
        public static IGridItem GridPartial(this HtmlHelper helper, IPublishedElement publishedElement)
        {
            var overrideGridItems = DependencyResolver.Current.GetServices <IGridItem>();

            var gridItem = overrideGridItems
                           .Where(x => x.ElementType == publishedElement.GetType())
                           .Cast <IGridItem>()
                           .FirstOrDefault();

            if (gridItem == null)
            {
                var gridItems = DependencyResolver.Current.GetService <IGridItemInternal[]>();

                return(gridItems
                       .Where(x => x.ElementType == publishedElement.GetType())
                       .Cast <IGridItem>()
                       .FirstOrDefault());
            }
            else
            {
                return(gridItem);
            }
        }
        /// <inheritdoc />
        public IPublishedElement CreateModel(IPublishedElement element)
        {
            // fail fast
            if (_modelInfos is null || element.ContentType.Alias is null || !_modelInfos.TryGetValue(element.ContentType.Alias, out var modelInfo))
            {
                return(element);
            }

            // ReSharper disable once UseMethodIsInstanceOfType
            if (modelInfo.ParameterType?.IsAssignableFrom(element.GetType()) == false)
            {
                throw new InvalidOperationException($"Model {modelInfo.ModelType} expects argument of type {modelInfo.ParameterType.FullName}, but got {element.GetType().FullName}.");
            }

            // can cast, because we checked when creating the ctor
            return((IPublishedElement)modelInfo.Ctor !(element, _publishedValueFallback));
        }
        /// <inheritdoc />
        public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
        {
            // NOTE: The intermediate object is just a json string, we don't actually convert from source -> intermediate since source is always just a json string

            using (_proflog.DebugDuration <BlockListPropertyValueConverter>($"ConvertPropertyToBlockList ({propertyType.DataType.Id})"))
            {
                var configuration            = propertyType.DataType.ConfigurationAs <BlockListConfiguration>();
                var blockConfigMap           = configuration.Blocks.ToDictionary(x => x.ContentElementTypeKey);
                var validSettingElementTypes = blockConfigMap.Values.Select(x => x.SettingsElementTypeKey).Where(x => x.HasValue).Distinct().ToList();

                var contentPublishedElements  = new Dictionary <Guid, IPublishedElement>();
                var settingsPublishedElements = new Dictionary <Guid, IPublishedElement>();

                var layout = new List <BlockListItem>();

                var value = (string)inter;
                if (string.IsNullOrWhiteSpace(value))
                {
                    return(BlockListModel.Empty);
                }

                var converted = _blockListEditorDataConverter.Deserialize(value);
                if (converted.BlockValue.ContentData.Count == 0)
                {
                    return(BlockListModel.Empty);
                }

                var blockListLayout = converted.Layout.ToObject <IEnumerable <BlockListLayoutItem> >();

                // convert the content data
                foreach (var data in converted.BlockValue.ContentData)
                {
                    if (!blockConfigMap.ContainsKey(data.ContentTypeKey))
                    {
                        continue;
                    }

                    var element = _blockConverter.ConvertToElement(data, referenceCacheLevel, preview);
                    if (element == null)
                    {
                        continue;
                    }
                    contentPublishedElements[element.Key] = element;
                }
                // convert the settings data
                foreach (var data in converted.BlockValue.SettingsData)
                {
                    if (!validSettingElementTypes.Contains(data.ContentTypeKey))
                    {
                        continue;
                    }

                    var element = _blockConverter.ConvertToElement(data, referenceCacheLevel, preview);
                    if (element == null)
                    {
                        continue;
                    }
                    settingsPublishedElements[element.Key] = element;
                }

                // if there's no elements just return since if there's no data it doesn't matter what is stored in layout
                if (contentPublishedElements.Count == 0)
                {
                    return(BlockListModel.Empty);
                }

                foreach (var layoutItem in blockListLayout)
                {
                    // get the content reference
                    var contentGuidUdi = (GuidUdi)layoutItem.ContentUdi;
                    if (!contentPublishedElements.TryGetValue(contentGuidUdi.Guid, out var contentData))
                    {
                        continue;
                    }

                    // get the setting reference
                    IPublishedElement settingsData = null;
                    var settingGuidUdi             = layoutItem.SettingsUdi != null ? (GuidUdi)layoutItem.SettingsUdi : null;
                    if (settingGuidUdi != null)
                    {
                        settingsPublishedElements.TryGetValue(settingGuidUdi.Guid, out settingsData);
                    }

                    if (!contentData.ContentType.TryGetKey(out var contentTypeKey))
                    {
                        throw new InvalidOperationException("The content type was not of type " + typeof(IPublishedContentType2));
                    }

                    if (!blockConfigMap.TryGetValue(contentTypeKey, out var blockConfig))
                    {
                        continue;
                    }

                    // this can happen if they have a settings type, save content, remove the settings type, and display the front-end page before saving the content again
                    // we also ensure that the content type's match since maybe the settings type has been changed after this has been persisted.
                    if (settingsData != null)
                    {
                        if (!settingsData.ContentType.TryGetKey(out var settingsElementTypeKey))
                        {
                            throw new InvalidOperationException("The settings element type was not of type " + typeof(IPublishedContentType2));
                        }

                        if (!blockConfig.SettingsElementTypeKey.HasValue || settingsElementTypeKey != blockConfig.SettingsElementTypeKey)
                        {
                            settingsData = null;
                        }
                    }

                    var layoutType = typeof(BlockListItem <,>).MakeGenericType(contentData.GetType(), settingsData?.GetType() ?? typeof(IPublishedElement));
                    var layoutRef  = (BlockListItem)Activator.CreateInstance(layoutType, contentGuidUdi, contentData, settingGuidUdi, settingsData);

                    layout.Add(layoutRef);
                }

                var model = new BlockListModel(layout);
                return(model);
            }
        }
        public override object ConvertIntermediateToObject(IPublishedElement owner, IPublishedPropertyType propertyType, PropertyCacheLevel referenceCacheLevel, object inter, bool preview)
        {
            ContentBlocksModelValue modelValue = _deserializer.Deserialize(inter?.ToString());

            if (modelValue == null)
            {
                return(Rendering.ContentBlocks.Empty);
            }

            var config = propertyType.DataType.ConfigurationAs <ContentBlocksConfiguration>();

            var header = config.Structure.HasFlag(Structure.Header)
                ? createViewModel(modelValue.Header)
                : null;

            var blocks = config.Structure.HasFlag(Structure.Blocks)
                ? modelValue.Blocks.Select(createViewModel).Where(rm => rm != null).ToList()
                : Enumerable.Empty <IContentBlockViewModel>();

            return(new Rendering.ContentBlocks
            {
                Header = header,
                Blocks = blocks
            });

            IContentBlockViewModel createViewModel(ContentBlockModelValue block)
            {
                if (block == null || block.IsDisabled)
                {
                    return(null);
                }

                IContentBlockDefinitionRepository definitionRepository = Current.Factory.GetInstance <IContentBlockDefinitionRepository>();

                if (definitionRepository == null)
                {
                    return(null);
                }

                IContentBlockDefinition definition = definitionRepository.GetById(block.DefinitionId);

                if (definition == null || definition.Layouts == null || definition.Layouts.Any() == false)
                {
                    return(null);
                }

                IContentBlockLayout layout = definition.Layouts.FirstOrDefault(l => l.Id == block.LayoutId);

                if (layout == null)
                {
                    return(null);
                }

                IPublishedElement content = _nestedContentSingleValueConverter.ConvertIntermediateToObject(owner, propertyType, referenceCacheLevel, block?.Content?.ToString(), preview) as IPublishedElement;

                if (content == null)
                {
                    return(null);
                }

                var contentType = content.GetType();
                var genericViewModelFactoryType = typeof(IContentBlockViewModelFactory <>).MakeGenericType(new[] { contentType });
                var viewModelFactory            = Current.Factory.GetInstance(genericViewModelFactoryType) as IContentBlockViewModelFactory;

                if (viewModelFactory == null)
                {
                    return(null);
                }

                return(viewModelFactory.Create(content, block.Id, block.DefinitionId, block.LayoutId));
            }
        }