예제 #1
0
        private static MediaVersionDto BuildMediaVersionDto(PropertyEditorCollection propertyEditors, IMedia entity, ContentDto contentDto)
        {
            // try to get a path from the string being stored for media
            // TODO: only considering umbracoFile

            string path = null;

            if (entity.Properties.TryGetValue(Constants.Conventions.Media.File, out var property) &&
                propertyEditors.TryGet(property.PropertyType.PropertyEditorAlias, out var editor) &&
                editor is IDataEditorWithMediaPath dataEditor)
            {
                var value = property.GetValue();
                path = dataEditor.GetMediaPath(value);
            }

            var dto = new MediaVersionDto
            {
                Id   = entity.VersionId,
                Path = path,

                ContentVersionDto = BuildContentVersionDto(entity, contentDto)
            };

            return(dto);
        }
        public void Initialize()
        {
            DataTypeService.Deleting += StopFormRteDelete;

            if (_dataTypeService.GetDataType(FormRteName) != null || !_propertyEditorCollection.TryGet(Constants.PropertyEditors.Aliases.TinyMce, out var editor))
            {
                return;
            }

            var formsRTE = new DataType(editor)
            {
                Name          = FormRteName,
                Configuration = new Dictionary <string, object>
                {
                    ["editor"] = new Dictionary <string, object>
                    {
                        ["toolbar"]      = new[] { "ace", "bold", "italic", "bullist", "numlist", "link", "umbmediapicker" },
                        ["stylesheets"]  = new string[0],
                        ["maxImageSize"] = 500,
                        ["mode"]         = "classic"
                    },
                    ["hideLabel"]            = false,
                    ["ignoreUserStartNodes"] = false,
                    ["mediaParentId"]        = null
                }
            };

            _dataTypeService.Save(formsRTE);
        }
        private Dictionary <string, IPublishedProperty> MapProperties(ServiceContext services)
        {
            var contentType = this.contentType.Value;
            var properties  = this.content.Properties;

            var items = new Dictionary <string, IPublishedProperty>(StringComparer.InvariantCultureIgnoreCase);

            foreach (var propertyType in contentType.PropertyTypes)
            {
                var property = properties.FirstOrDefault(x => x.Alias.InvariantEquals(propertyType.DataType.EditorAlias));
                var value    = property?.GetValue();
                if (value != null)
                {
                    _propertyEditors.TryGet(propertyType.DataType.EditorAlias, out var editor);
                    if (editor != null)
                    {
                        value = editor.GetValueEditor().ConvertDbToString(property.PropertyType, value, services.DataTypeService);
                    }
                }

                items.Add(propertyType.DataType.EditorAlias, new UnpublishedProperty(propertyType, value));
            }

            return(items);
        }
        /// <inheritdoc />
        public virtual UrlInfo GetMediaUrl(UmbracoContext umbracoContext, IPublishedContent content,
                                           string propertyAlias, UrlMode mode, string culture, Uri current)
        {
            var prop = content.GetProperty(propertyAlias);

            // get the raw source value since this is what is used by IDataEditorWithMediaPath for processing
            var value = prop?.GetSourceValue(culture);

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

            var    propType = prop.PropertyType;
            string path     = null;

            if (_propertyEditors.TryGet(propType.EditorAlias, out var editor) &&
                editor is IDataEditorWithMediaPath dataEditor)
            {
                path = dataEditor.GetMediaPath(value);
            }

            var url = AssembleUrl(path, current, mode);

            return(url == null ? null : UrlInfo.Url(url.ToString(), culture));
        }
예제 #5
0
        // Umbraco.Code.MapAll -HasPrevalues
        private void Map(IDataType source, DataTypeBasic target, MapperContext context)
        {
            target.Id = source.Id;
            target.IsSystemDataType = SystemIds.Contains(source.Id);
            target.Key      = source.Key;
            target.Name     = source.Name;
            target.ParentId = source.ParentId;
            target.Path     = source.Path;
            target.Trashed  = source.Trashed;
            target.Udi      = Udi.Create(Constants.UdiEntityType.DataType, source.Key);

            if (!_propertyEditors.TryGet(source.EditorAlias, out var editor))
            {
                return;
            }

            target.Alias = editor.Alias;
            target.Group = editor.Group;
            target.Icon  = editor.Icon;
        }
    // TODO: We could further reduce circular dependencies with PropertyEditorCollection by not having IDataValueReference implemented
    // by property editors and instead just use the already built in IDataValueReferenceFactory and/or refactor that into a more normal collection
    public IEnumerable <UmbracoEntityReference> GetAllReferences(
        IPropertyCollection properties,
        PropertyEditorCollection propertyEditors)
    {
        var trackedRelations = new HashSet <UmbracoEntityReference>();

        foreach (IProperty p in properties)
        {
            if (!propertyEditors.TryGet(p.PropertyType.PropertyEditorAlias, out IDataEditor? editor))
            {
                continue;
            }

            // TODO: We will need to change this once we support tracking via variants/segments
            // for now, we are tracking values from ALL variants
            foreach (IPropertyValue propertyVal in p.Values)
            {
                var val = propertyVal.EditedValue;

                IDataValueEditor?valueEditor = editor?.GetValueEditor();
                if (valueEditor is IDataValueReference reference)
                {
                    IEnumerable <UmbracoEntityReference> refs = reference.GetReferences(val);
                    foreach (UmbracoEntityReference r in refs)
                    {
                        trackedRelations.Add(r);
                    }
                }

                // Loop over collection that may be add to existing property editors
                // implementation of GetReferences in IDataValueReference.
                // Allows developers to add support for references by a
                // package /property editor that did not implement IDataValueReference themselves
                foreach (IDataValueReferenceFactory item in this)
                {
                    // Check if this value reference is for this datatype/editor
                    // Then call it's GetReferences method - to see if the value stored
                    // in the dataeditor/property has referecnes to media/content items
                    if (item.IsForEditor(editor))
                    {
                        foreach (UmbracoEntityReference r in item.GetDataValueReference().GetReferences(val))
                        {
                            trackedRelations.Add(r);
                        }
                    }
                }
            }
        }

        return(trackedRelations);
    }
예제 #7
0
        public HttpResponseMessage GetPreview([FromBody] JObject data)
        {
            var config = data.ToObject <Dictionary <string, object> >();

            if (_propertyEditors.TryGet(DataListDataEditor.DataEditorAlias, out var propertyEditor) == true)
            {
                var alias = config.GetValueAs("alias", "preview");
                var configurationEditor = propertyEditor.GetConfigurationEditor();
                var valueEditorConfig   = configurationEditor.ToValueEditor(config);
                var valueEditor         = propertyEditor.GetValueEditor(config);

                return(Request.CreateResponse(HttpStatusCode.OK, new { config = valueEditorConfig, view = valueEditor.View, alias }));
            }

            return(Request.CreateResponse(HttpStatusCode.NotFound));
        }
예제 #8
0
    public static IDataType BuildEntity(DataTypeDto dto, PropertyEditorCollection editors, ILogger <IDataType> logger, IConfigurationEditorJsonSerializer serializer)
    {
        // Check we have an editor for the data type.
        if (!editors.TryGet(dto.EditorAlias, out IDataEditor? editor))
        {
            logger.LogWarning(
                "Could not find an editor with alias {EditorAlias}, treating as Label. " + "The site may fail to boot and/or load data types and run.", dto.EditorAlias);

            // Create as special type, which downstream can be handled by converting to a LabelPropertyEditor to make clear
            // the situation to the user.
            editor = new MissingPropertyEditor();
        }

        var dataType = new DataType(editor, serializer);

        try
        {
            dataType.DisableChangeTracking();

            dataType.CreateDate   = dto.NodeDto.CreateDate;
            dataType.DatabaseType = dto.DbType.EnumParse <ValueStorageType>(true);
            dataType.Id           = dto.NodeId;
            dataType.Key          = dto.NodeDto.UniqueId;
            dataType.Level        = dto.NodeDto.Level;
            dataType.UpdateDate   = dto.NodeDto.CreateDate;
            dataType.Name         = dto.NodeDto.Text;
            dataType.ParentId     = dto.NodeDto.ParentId;
            dataType.Path         = dto.NodeDto.Path;
            dataType.SortOrder    = dto.NodeDto.SortOrder;
            dataType.Trashed      = dto.NodeDto.Trashed;
            dataType.CreatorId    = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;

            dataType.SetLazyConfiguration(dto.Configuration);

            // reset dirty initial properties (U4-1946)
            dataType.ResetDirtyProperties(false);
            return(dataType);
        }
        finally
        {
            dataType.EnableChangeTracking();
        }
    }
예제 #9
0
        private static void SetUploadFile(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, Stream filestream, string culture = null, string segment = null)
        {
            var property = GetProperty(content, contentTypeBaseServiceProvider, propertyTypeAlias);

            // Fixes https://github.com/umbraco/Umbraco-CMS/issues/3937 - Assigning a new file to an
            // existing IMedia with extension SetValue causes exception 'Illegal characters in path'
            string oldpath = null;
            var    value   = property.GetValue(culture, segment);

            if (PropertyEditors.TryGet(propertyTypeAlias, out var editor) &&
                editor is IDataEditorWithMediaPath dataEditor)
            {
                var svalue = dataEditor.GetMediaPath(value);
                oldpath = MediaFileSystem.GetRelativePath(svalue);
            }

            var filepath = MediaFileSystem.StoreFile(content, property.PropertyType, filename, filestream, oldpath);

            property.SetValue(MediaFileSystem.GetUrl(filepath), culture, segment);
        }
예제 #10
0
        public static IDataType BuildEntity(DataTypeDto dto, PropertyEditorCollection editors, ILogger logger)
        {
            if (!editors.TryGet(dto.EditorAlias, out var editor))
            {
                logger.Warn(typeof(DataType), "Could not find an editor with alias {EditorAlias}, treating as Label."
                            + " The site may fail to boot and / or load data types and run.", dto.EditorAlias);
                //convert to label
                editor = new LabelPropertyEditor(logger);
            }

            var dataType = new DataType(editor);

            try
            {
                dataType.DisableChangeTracking();

                dataType.CreateDate   = dto.NodeDto.CreateDate;
                dataType.DatabaseType = dto.DbType.EnumParse <ValueStorageType>(true);
                dataType.Id           = dto.NodeId;
                dataType.Key          = dto.NodeDto.UniqueId;
                dataType.Level        = dto.NodeDto.Level;
                dataType.UpdateDate   = dto.NodeDto.CreateDate;
                dataType.Name         = dto.NodeDto.Text;
                dataType.ParentId     = dto.NodeDto.ParentId;
                dataType.Path         = dto.NodeDto.Path;
                dataType.SortOrder    = dto.NodeDto.SortOrder;
                dataType.Trashed      = dto.NodeDto.Trashed;
                dataType.CreatorId    = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;

                dataType.SetLazyConfiguration(dto.Configuration);

                // reset dirty initial properties (U4-1946)
                dataType.ResetDirtyProperties(false);
                return(dataType);
            }
            finally
            {
                dataType.EnableChangeTracking();
            }
        }
예제 #11
0
        private void CreateExampleBlockDataType(string contentTypeAlias, Guid dataTypeKey)
        {
            if (_dataTypeService.GetDataType(dataTypeKey) != null)
            {
                // Already there
                return;
            }

            if (!(_propertyEditors.TryGet("Umbraco.NestedContent", out var editor) && editor is NestedContentPropertyEditor nestedContentEditor))
            {
                throw new InvalidOperationException("Nested Content property editor not found!");
            }

            var dataType = new DataType(nestedContentEditor, -1)
            {
                Name          = "Perplex.ContentBlocks - ExampleBlock",
                Key           = dataTypeKey,
                Configuration = new NestedContentConfiguration
                {
                    ConfirmDeletes = false,
                    HideLabel      = true,
                    MinItems       = 1,
                    MaxItems       = 1,
                    ShowIcons      = false,
                    ContentTypes   = new[]
                    {
                        new NestedContentConfiguration.ContentType
                        {
                            Alias    = contentTypeAlias,
                            TabAlias = "Content",
                            Template = "{{title}}"
                        }
                    }
                }
            };

            _dataTypeService.Save(dataType);
        }
예제 #12
0
        public static IDataType BuildEntity(DataTypeDto dto, PropertyEditorCollection editors)
        {
            if (!editors.TryGet(dto.EditorAlias, out var editor))
            {
                throw new InvalidOperationException($"Could not find an editor with alias \"{dto.EditorAlias}\".");
            }

            var dataType = new DataType(editor);

            try
            {
                dataType.DisableChangeTracking();

                dataType.CreateDate   = dto.NodeDto.CreateDate;
                dataType.DatabaseType = dto.DbType.EnumParse <ValueStorageType>(true);
                dataType.Id           = dto.NodeId;
                dataType.Key          = dto.NodeDto.UniqueId;
                dataType.Level        = dto.NodeDto.Level;
                dataType.UpdateDate   = dto.NodeDto.CreateDate;
                dataType.Name         = dto.NodeDto.Text;
                dataType.ParentId     = dto.NodeDto.ParentId;
                dataType.Path         = dto.NodeDto.Path;
                dataType.SortOrder    = dto.NodeDto.SortOrder;
                dataType.Trashed      = dto.NodeDto.Trashed;
                dataType.CreatorId    = dto.NodeDto.UserId ?? Constants.Security.UnknownUserId;

                dataType.SetLazyConfiguration(dto.Configuration);

                // reset dirty initial properties (U4-1946)
                dataType.ResetDirtyProperties(false);
                return(dataType);
            }
            finally
            {
                dataType.EnableChangeTracking();
            }
        }
예제 #13
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);
        }
        public override PipelineResult <InstallPipelineContext> Execute(PipelineArgs <InstallPipelineContext> args)
        {
            // Theme Color Picker
            var currentColorPicker = _dataTypeService.GetDataType(VendrCheckoutConstants.DataTypes.Guids.ThemeColorPickerGuid);

            if (currentColorPicker == null)
            {
                if (_propertyEditors.TryGet(Constants.PropertyEditors.Aliases.ColorPicker, out IDataEditor editor))
                {
                    var dataType = CreateDataType(editor, x =>
                    {
                        x.Key           = VendrCheckoutConstants.DataTypes.Guids.ThemeColorPickerGuid;
                        x.Name          = "[Vendr Checkout] Theme Color Picker";
                        x.DatabaseType  = ValueStorageType.Nvarchar;
                        x.Configuration = new ColorPickerConfiguration
                        {
                            Items = VendrCheckoutConstants.ColorMap.Select((kvp, idx) => new ValueListConfiguration.ValueListItem
                            {
                                Id    = idx,
                                Value = "{\"value\":\"" + kvp.Key + "\", \"label\":\"" + kvp.Value + "\"}"
                            }).ToList(),
                            UseLabel = false
                        };
                    });

                    _dataTypeService.Save(dataType);
                }
            }
            else
            {
                currentColorPicker.Configuration = new ColorPickerConfiguration
                {
                    Items = VendrCheckoutConstants.ColorMap.Select((kvp, idx) => new ValueListConfiguration.ValueListItem
                    {
                        Id    = idx,
                        Value = "{\"value\":\"" + kvp.Key + "\", \"label\":\"" + kvp.Value + "\"}"
                    }).ToList(),
                    UseLabel = false
                };

                _dataTypeService.Save(currentColorPicker);
            }

            // Step Picker
            var stepPickerItems = new List <ValueListConfiguration.ValueListItem>
            {
                new ValueListConfiguration.ValueListItem {
                    Id = 1, Value = "Information"
                },
                new ValueListConfiguration.ValueListItem {
                    Id = 2, Value = "ShippingMethod"
                },
                new ValueListConfiguration.ValueListItem {
                    Id = 3, Value = "PaymentMethod"
                },
                new ValueListConfiguration.ValueListItem {
                    Id = 4, Value = "Review"
                },
                new ValueListConfiguration.ValueListItem {
                    Id = 5, Value = "Payment"
                },
                new ValueListConfiguration.ValueListItem {
                    Id = 6, Value = "Confirmation"
                }
            };

            var currentStepPicker = _dataTypeService.GetDataType(VendrCheckoutConstants.DataTypes.Guids.StepPickerGuid);

            if (currentStepPicker == null)
            {
                if (_propertyEditors.TryGet(Constants.PropertyEditors.Aliases.DropDownListFlexible, out IDataEditor editor))
                {
                    var dataType = CreateDataType(editor, x =>
                    {
                        x.Key           = VendrCheckoutConstants.DataTypes.Guids.StepPickerGuid;
                        x.Name          = "[Vendr Checkout] Step Picker";
                        x.DatabaseType  = ValueStorageType.Nvarchar;
                        x.Configuration = new DropDownFlexibleConfiguration
                        {
                            Items    = stepPickerItems,
                            Multiple = false
                        };
                    });

                    _dataTypeService.Save(dataType);
                }
            }
            else
            {
                currentStepPicker.Configuration = new DropDownFlexibleConfiguration
                {
                    Items    = stepPickerItems,
                    Multiple = false
                };

                _dataTypeService.Save(currentStepPicker);
            }

            // Continue the pipeline
            return(Ok());
        }
예제 #15
0
        protected override void Migrate()
        {
            // drop and create columns
            Delete.Column("pk").FromTable("cmsDataType").Do();

            // rename the table
            Rename.Table("cmsDataType").To(Cms.Core.Constants.DatabaseSchema.Tables.DataType).Do();

            // create column
            AddColumn <DataTypeDto>(Cms.Core.Constants.DatabaseSchema.Tables.DataType, "config");
            Execute.Sql(Sql().Update <DataTypeDto>(u => u.Set(x => x.Configuration, string.Empty))).Do();

            // renames
            Execute.Sql(Sql()
                        .Update <DataTypeDto>(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
                        .Where <DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias")).Do();

            // from preValues to configuration...
            var sql = Sql()
                      .Select <DataTypeDto>()
                      .AndSelect <PreValueDto>(x => x.Id, x => x.Alias, x => x.SortOrder, x => x.Value)
                      .From <DataTypeDto>()
                      .InnerJoin <PreValueDto>().On <DataTypeDto, PreValueDto>((left, right) => left.NodeId == right.NodeId)
                      .OrderBy <DataTypeDto>(x => x.NodeId)
                      .AndBy <PreValueDto>(x => x.SortOrder);

            var dtos = Database.Fetch <PreValueDto>(sql).GroupBy(x => x.NodeId);

            foreach (var group in dtos)
            {
                var dataType = Database.Fetch <DataTypeDto>(Sql()
                                                            .Select <DataTypeDto>()
                                                            .From <DataTypeDto>()
                                                            .Where <DataTypeDto>(x => x.NodeId == group.Key)).First();

                // check for duplicate aliases
                var aliases = group.Select(x => x.Alias).Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
                if (aliases.Distinct().Count() != aliases.Length)
                {
                    throw new InvalidOperationException($"Cannot migrate prevalues for datatype id={dataType.NodeId}, editor={dataType.EditorAlias}: duplicate alias.");
                }

                // handle null/empty aliases
                int index      = 0;
                var dictionary = group.ToDictionary(x => string.IsNullOrWhiteSpace(x.Alias) ? index++.ToString() : x.Alias);

                // migrate the preValues to configuration
                var migrator = _preValueMigrators.GetMigrator(dataType.EditorAlias) ?? new DefaultPreValueMigrator();
                var config   = migrator.GetConfiguration(dataType.NodeId, dataType.EditorAlias, dictionary);
                var json     = _configurationEditorJsonSerializer.Serialize(config);

                // validate - and kill the migration if it fails
                var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
                if (newAlias == null)
                {
                    if (!LegacyAliases.Contains(dataType.EditorAlias))
                    {
                        _logger.LogWarning(
                            "Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
                            + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
                            dataType.NodeId, dataType.EditorAlias);
                    }
                }
                else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
                {
                    if (!LegacyAliases.Contains(newAlias))
                    {
                        _logger.LogWarning("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
                                           + " because no property editor with that alias was found."
                                           + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
                                           dataType.NodeId, newAlias, dataType.EditorAlias);
                    }
                }
                else
                {
                    var configEditor = propertyEditor.GetConfigurationEditor();
                    try
                    {
                        var _ = configEditor.FromDatabase(json, _configurationEditorJsonSerializer);
                    }
                    catch (Exception e)
                    {
                        _logger.LogWarning(e, "Failed to validate configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})."
                                           + " Please fix the configuration and ensure it is valid. The site may fail to start and / or load data types and run.",
                                           dataType.NodeId, newAlias, dataType.EditorAlias);
                    }
                }

                // update
                dataType.Configuration = _configurationEditorJsonSerializer.Serialize(config);
                Database.Update(dataType);
            }
        }
예제 #16
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());
        }
예제 #17
0
            public void OnActionExecuting(ActionExecutingContext context)
            {
                var dataType = (DataTypeSave?)context.ActionArguments["dataType"];

                if (dataType is not null)
                {
                    dataType.Name  = dataType.Name?.CleanForXss('[', ']', '(', ')', ':');
                    dataType.Alias = dataType.Alias == null ? dataType.Name ! : dataType.Alias.CleanForXss('[', ']', '(', ')', ':');
                }

                // get the property editor, ensuring that it exits
                if (!_propertyEditorCollection.TryGet(dataType?.EditorAlias, out var propertyEditor))
                {
                    var message = $"Property editor \"{dataType?.EditorAlias}\" was not found.";
                    context.Result = new UmbracoProblemResult(message, HttpStatusCode.NotFound);
                    return;
                }

                if (dataType is null)
                {
                    return;
                }

                // assign
                dataType.PropertyEditor = propertyEditor;

                // validate that the data type exists, or create one if required
                IDataType?persisted;

                switch (dataType.Action)
                {
                case ContentSaveAction.Save:
                    persisted = _dataTypeService.GetDataType(Convert.ToInt32(dataType.Id));
                    if (persisted == null)
                    {
                        var message = $"Data type with id {dataType.Id} was not found.";
                        context.Result = new UmbracoProblemResult(message, HttpStatusCode.NotFound);
                        return;
                    }
                    // map the model to the persisted instance
                    _umbracoMapper.Map(dataType, persisted);
                    break;

                case ContentSaveAction.SaveNew:
                    // create the persisted model from mapping the saved model
                    persisted = _umbracoMapper.Map <IDataType>(dataType);
                    ((DataType?)persisted)?.ResetIdentity();
                    break;

                default:
                    context.Result = new UmbracoProblemResult($"Data type action {dataType.Action} was not found.", HttpStatusCode.NotFound);
                    return;
                }

                // assign (so it's available in the action)
                dataType.PersistedDataType = persisted;

                // validate the configuration
                // which is posted as a set of fields with key (string) and value (object)
                var configurationEditor = propertyEditor.GetConfigurationEditor();

                if (dataType.ConfigurationFields is not null)
                {
                    foreach (var field in dataType.ConfigurationFields)
                    {
                        var editorField = configurationEditor.Fields.SingleOrDefault(x => x.Key == field.Key);
                        if (editorField == null)
                        {
                            continue;
                        }

                        // run each IValueValidator (with null valueType and dataTypeConfiguration: not relevant here)
                        foreach (var validator in editorField.Validators)
                        {
                            foreach (var result in validator.Validate(field.Value, null, null))
                            {
                                context.ModelState.AddValidationError(result, "Properties", field.Key ?? string.Empty);
                            }
                        }
                    }
                }

                if (context.ModelState.IsValid == false)
                {
                    // if it is not valid, do not continue and return the model state
                    context.Result = new ValidationErrorResult(context.ModelState);
                }
            }
예제 #18
0
        public override void Migrate()
        {
            // drop and create columns
            Delete.Column("pk").FromTable("cmsDataType").Do();

            // rename the table
            Rename.Table("cmsDataType").To(Constants.DatabaseSchema.Tables.DataType).Do();

            // create column
            AddColumn <DataTypeDto>(Constants.DatabaseSchema.Tables.DataType, "config");
            Execute.Sql(Sql().Update <DataTypeDto>(u => u.Set(x => x.Configuration, string.Empty))).Do();

            // renames
            Execute.Sql(Sql()
                        .Update <DataTypeDto>(u => u.Set(x => x.EditorAlias, "Umbraco.ColorPicker"))
                        .Where <DataTypeDto>(x => x.EditorAlias == "Umbraco.ColorPickerAlias")).Do();

            // from preValues to configuration...
            var sql = Sql()
                      .Select <DataTypeDto>()
                      .AndSelect <PreValueDto>(x => x.Id, x => x.Alias, x => x.SortOrder, x => x.Value)
                      .From <DataTypeDto>()
                      .InnerJoin <PreValueDto>().On <DataTypeDto, PreValueDto>((left, right) => left.NodeId == right.NodeId)
                      .OrderBy <DataTypeDto>(x => x.NodeId)
                      .AndBy <PreValueDto>(x => x.SortOrder);

            var dtos = Database.Fetch <PreValueDto>(sql).GroupBy(x => x.NodeId);

            foreach (var group in dtos)
            {
                var dataType = Database.Fetch <DataTypeDto>(Sql()
                                                            .Select <DataTypeDto>()
                                                            .From <DataTypeDto>()
                                                            .Where <DataTypeDto>(x => x.NodeId == group.Key)).First();

                // migrate the preValues to configuration
                var migrator = _preValueMigrators.GetMigrator(dataType.EditorAlias) ?? new DefaultPreValueMigrator();
                var config   = migrator.GetConfiguration(dataType.NodeId, dataType.EditorAlias, group.ToDictionary(x => x.Alias, x => x));
                var json     = JsonConvert.SerializeObject(config);

                // validate - and kill the migration if it fails
                var newAlias = migrator.GetNewAlias(dataType.EditorAlias);
                if (newAlias == null)
                {
                    _logger.Warn <DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {EditorAlias}."
                                                     + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
                                                     dataType.NodeId, dataType.EditorAlias);
                }
                else if (!_propertyEditors.TryGet(newAlias, out var propertyEditor))
                {
                    _logger.Warn <DataTypeMigration>("Skipping validation of configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})"
                                                     + " because no property editor with that alias was found."
                                                     + " Please ensure that the configuration is valid. The site may fail to start and / or load data types and run.",
                                                     dataType.NodeId, newAlias, dataType.EditorAlias);
                }
                else
                {
                    var configEditor = propertyEditor.GetConfigurationEditor();
                    try
                    {
                        var _ = configEditor.FromDatabase(json);
                    }
                    catch (Exception e)
                    {
                        _logger.Warn <DataTypeMigration>(e, "Failed to validate configuration for data type {NodeId} : {NewEditorAlias} (was: {EditorAlias})."
                                                         + " Please fix the configuration and ensure it is valid. The site may fail to start and / or load data types and run.",
                                                         dataType.NodeId, newAlias, dataType.EditorAlias);
                    }
                }

                // update
                dataType.Configuration = JsonConvert.SerializeObject(config);
                Database.Update(dataType);
            }
        }
예제 #19
0
 /// <summary>
 ///     It is a converter for any value type that is "JSON"
 ///     Unless it's in the Excluded Property Editors list
 ///     The new MediaPicker 3 stores JSON but we want to use its own ValueConvertor
 /// </summary>
 /// <param name="propertyType"></param>
 /// <returns></returns>
 public override bool IsConverter(IPublishedPropertyType propertyType) =>
 _propertyEditors.TryGet(propertyType.EditorAlias, out IDataEditor? editor) &&
 editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json) &&
 _excludedPropertyEditors.Contains(propertyType.EditorAlias) == false;
예제 #20
0
 /// <summary>
 /// It is a converter for any value type that is "JSON"
 /// </summary>
 /// <param name="propertyType"></param>
 /// <returns></returns>
 public override bool IsConverter(PublishedPropertyType propertyType)
 {
     return(_propertyEditors.TryGet(propertyType.EditorAlias, out var editor) &&
            editor.GetValueEditor().ValueType.InvariantEquals(ValueTypes.Json));
 }