Beispiel #1
0
        private PropertyCollection GetPropertyCollection(int id, Guid versionId, IMediaType contentType, DateTime createDate, DateTime updateDate)
        {
            var sql = new Sql();

            sql.Select("*")
            .From <PropertyDataDto>()
            .InnerJoin <PropertyTypeDto>()
            .On <PropertyDataDto, PropertyTypeDto>(left => left.PropertyTypeId, right => right.Id)
            .Where <PropertyDataDto>(x => x.NodeId == id)
            .Where <PropertyDataDto>(x => x.VersionId == versionId);

            var propertyDataDtos = Database.Fetch <PropertyDataDto, PropertyTypeDto>(sql);
            var propertyFactory  = new PropertyFactory(contentType, versionId, id, createDate, updateDate);
            var properties       = propertyFactory.BuildEntity(propertyDataDtos);

            var newProperties = properties.Where(x => x.HasIdentity == false);

            foreach (var property in newProperties)
            {
                var propertyDataDto = new PropertyDataDto {
                    NodeId = id, PropertyTypeId = property.PropertyTypeId, VersionId = versionId
                };
                int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));

                property.Version = versionId;
                property.Id      = primaryKey;
            }

            return(new PropertyCollection(properties));
        }
        //fixme - see https://github.com/umbraco/Umbraco-CMS/pull/3460#issuecomment-434903930 we need to not load any property data at all for media
        private void BuildProperty(EntitySlim entity, PropertyDataDto pdto)
        {
            // explain ?!
            var value = string.IsNullOrWhiteSpace(pdto.TextValue)
                ? pdto.VarcharValue
                : pdto.TextValue.ConvertToJsonIfPossible();

            entity.AdditionalData[pdto.PropertyTypeDto.Alias] = new EntitySlim.PropertySlim(pdto.PropertyTypeDto.DataTypeDto.EditorAlias, value);
        }
        private bool UpdateNestedPropertyDataDto(PropertyDataDto pd)
        {
            if (UpdateNestedContent(pd.TextValue, out string newValue))
            {
                pd.TextValue = newValue;
                return(true);
            }

            return(false);
        }
    private static PropertyDataDto BuildDto(int versionId, IProperty property, int?languageId, string?segment, object?value)
    {
        var dto = new PropertyDataDto {
            VersionId = versionId, PropertyTypeId = property.PropertyTypeId
        };

        if (languageId.HasValue)
        {
            dto.LanguageId = languageId;
        }

        if (segment != null)
        {
            dto.Segment = segment;
        }

        if (property.ValueStorageType == ValueStorageType.Integer)
        {
            if (value is bool || property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.Aliases.Boolean)
            {
                dto.IntegerValue = value != null && string.IsNullOrEmpty(value.ToString()) ? 0 : Convert.ToInt32(value);
            }
            else if (value != null && string.IsNullOrWhiteSpace(value.ToString()) == false &&
                     int.TryParse(value.ToString(), NumberStyles.Integer, CultureInfo.InvariantCulture, out var val))
            {
                dto.IntegerValue = val;
            }
        }
        else if (property.ValueStorageType == ValueStorageType.Decimal && value != null)
        {
            if (decimal.TryParse(value.ToString(), out var val))
            {
                dto.DecimalValue = val; // property value should be normalized already
            }
        }
        else if (property.ValueStorageType == ValueStorageType.Date && value != null &&
                 string.IsNullOrWhiteSpace(value.ToString()) == false)
        {
            if (DateTime.TryParse(value.ToString(), out DateTime date))
            {
                dto.DateValue = date;
            }
        }
        else if (property.ValueStorageType == ValueStorageType.Ntext && value != null)
        {
            dto.TextValue = value.ToString();
        }
        else if (property.ValueStorageType == ValueStorageType.Nvarchar && value != null)
        {
            dto.VarcharValue = value.ToString();
        }

        return(dto);
    }
        public IEnumerable <PropertyDataDto> BuildDto(IEnumerable <Property> properties)
        {
            var propertyDataDtos = new List <PropertyDataDto>();

            foreach (var property in properties)
            {
                var dto = new PropertyDataDto {
                    NodeId = _id, PropertyTypeId = property.PropertyTypeId, VersionId = _version
                };

                //Check if property has an Id and set it, so that it can be updated if it already exists
                if (property.HasIdentity)
                {
                    dto.Id = property.Id;
                }

                if (property.DataTypeDatabaseType == DataTypeDatabaseType.Integer)
                {
                    if (property.Value is bool || property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.TrueFalseAlias)
                    {
                        dto.Integer = property.Value != null && string.IsNullOrEmpty(property.Value.ToString())
                                          ? 0
                                          : Convert.ToInt32(property.Value);
                    }
                    else
                    {
                        int val;
                        if ((property.Value != null && string.IsNullOrWhiteSpace(property.Value.ToString()) == false) && int.TryParse(property.Value.ToString(), out val))
                        {
                            dto.Integer = val;
                        }
                    }
                }
                else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Date && property.Value != null && string.IsNullOrWhiteSpace(property.Value.ToString()) == false)
                {
                    DateTime date;
                    if (DateTime.TryParse(property.Value.ToString(), out date))
                    {
                        dto.Date = date;
                    }
                }
                else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Ntext && property.Value != null)
                {
                    dto.Text = property.Value.ToString();
                }
                else if (property.DataTypeDatabaseType == DataTypeDatabaseType.Nvarchar && property.Value != null)
                {
                    dto.VarChar = property.Value.ToString();
                }

                propertyDataDtos.Add(dto);
            }
            return(propertyDataDtos);
        }
Beispiel #6
0
        private bool UpdateRadioOrCheckboxPropertyDataDto(PropertyDataDto propData, ValueListConfiguration config, bool singleValue)
        {
            //Get the INT ids stored for this property/drop down
            int[] ids = null;
            if (!propData.VarcharValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.VarcharValue);
            }
            else if (!propData.TextValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.TextValue);
            }
            else if (propData.IntegerValue.HasValue)
            {
                ids = new[] { propData.IntegerValue.Value };
            }

            //if there are INT ids, convert them to values based on the configuration
            if (ids == null || ids.Length <= 0)
            {
                return(false);
            }

            //map the ids to values
            var values     = new List <string>();
            var canConvert = true;

            foreach (var id in ids)
            {
                var val = config.Items.FirstOrDefault(x => x.Id == id);
                if (val != null)
                {
                    values.Add(val.Value);
                }
                else
                {
                    Logger.Warn <DropDownPropertyEditorsMigration>(
                        "Could not find associated data type configuration for stored Id {DataTypeId}", id);
                    canConvert = false;
                }
            }

            if (!canConvert)
            {
                return(false);
            }

            //The radio button only supports selecting a single value, so if there are multiple for some insane reason we can only use the first
            propData.VarcharValue = singleValue ? values[0] : JsonConvert.SerializeObject(values);
            propData.TextValue    = null;
            propData.IntegerValue = null;
            return(true);
        }
Beispiel #7
0
    internal bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config, bool isMultiple)
    {
        // Get the INT ids stored for this property/drop down
        int[]? ids = null;
        if (!propData.VarcharValue.IsNullOrWhiteSpace())
        {
            ids = ConvertStringValues(propData.VarcharValue);
        }
        else if (!propData.TextValue.IsNullOrWhiteSpace())
        {
            ids = ConvertStringValues(propData.TextValue);
        }
        else if (propData.IntegerValue.HasValue)
        {
            ids = new[] { propData.IntegerValue.Value };
        }

        // if there are INT ids, convert them to values based on the configuration
        if (ids == null || ids.Length <= 0)
        {
            return(false);
        }

        // map ids to values
        var values     = new List <string>();
        var canConvert = true;

        foreach (var id in ids)
        {
            ValueListConfiguration.ValueListItem?val = config.Items.FirstOrDefault(x => x.Id == id);
            if (val?.Value != null)
            {
                values.Add(val.Value);
                continue;
            }

            Logger.LogWarning(
                "Could not find PropertyData {PropertyDataId} value '{PropertyValue}' in the datatype configuration: {Values}.",
                propData.Id, id, string.Join(", ", config.Items.Select(x => x.Id + ":" + x.Value)));
            canConvert = false;
        }

        if (!canConvert)
        {
            return(false);
        }

        propData.VarcharValue = isMultiple ? JsonConvert.SerializeObject(values) : values[0];
        propData.TextValue    = null;
        propData.IntegerValue = null;
        return(true);
    }
        private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueStorageType valueType)
        {
            //Get the INT ids stored for this property/drop down
            int[] ids = null;
            if (!propData.VarcharValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.VarcharValue);
            }
            else if (!propData.TextValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.TextValue);
            }
            else if (propData.IntegerValue.HasValue)
            {
                ids = new[] { propData.IntegerValue.Value };
            }

            if (ids == null || ids.Length <= 0)
            {
                return(false);
            }

            // map ids to values
            var values     = new List <Udi>();
            var canConvert = true;

            foreach (var id in ids)
            {
                if (_nodeIdToKey.Value.TryGetValue(id, out var node))
                {
                    values.Add(Udi.Create(ObjectTypes.GetUdiType(node.NodeObjectType.Value), node.UniqueId));
                }
            }

            if (!canConvert)
            {
                return(false);
            }

            propData.IntegerValue = null;
            if (valueType == ValueStorageType.Ntext)
            {
                propData.TextValue    = String.Join(",", values);
                propData.VarcharValue = null;
            }
            else if (valueType == ValueStorageType.Nvarchar)
            {
                propData.TextValue    = null;
                propData.VarcharValue = String.Join(",", values);
            }
            return(true);
        }
        private string UpdateValueList(string propertyValue, ValueListConfiguration config, bool isMultiple)
        {
            var propData = new PropertyDataDto {
                VarcharValue = propertyValue
            };

            if (UpdatePropertyDataDto(propData, config, isMultiple: isMultiple))
            {
                return(propData.VarcharValue);
            }

            return(propertyValue);
        }
Beispiel #10
0
        private bool UpdatePropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
        {
            //Get the INT ids stored for this property/drop down
            int[] ids = null;
            if (!propData.VarcharValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.VarcharValue);
            }
            else if (!propData.TextValue.IsNullOrWhiteSpace())
            {
                ids = ConvertStringValues(propData.TextValue);
            }
            else if (propData.IntegerValue.HasValue)
            {
                ids = new[] { propData.IntegerValue.Value };
            }

            //if there are INT ids, convert them to values based on the configured pre-values
            if (ids != null && ids.Length > 0)
            {
                //map the ids to values
                var vals       = new List <string>();
                var canConvert = true;
                foreach (var id in ids)
                {
                    var val = config.Items.FirstOrDefault(x => x.Id == id);
                    if (val != null)
                    {
                        vals.Add(val.Value);
                    }
                    else
                    {
                        Logger.Warn <DropDownPropertyEditorsMigration>(
                            "Could not find associated data type configuration for stored Id {DataTypeId}", id);
                        canConvert = false;
                    }
                }
                if (canConvert)
                {
                    propData.VarcharValue = string.Join(",", vals);
                    propData.TextValue    = null;
                    propData.IntegerValue = null;
                    return(true);
                }
            }

            return(false);
        }
Beispiel #11
0
        private bool UpdateDropDownPropertyDataDto(PropertyDataDto propData, ValueListConfiguration config)
        {
            //Get the INT ids stored for this property/drop down
            var values = propData.VarcharValue.Split(new [] { "," }, StringSplitOptions.RemoveEmptyEntries);

            //if there are INT ids, convert them to values based on the configuration
            if (values == null || values.Length <= 0)
            {
                return(false);
            }

            //The radio button only supports selecting a single value, so if there are multiple for some insane reason we can only use the first
            propData.VarcharValue = JsonConvert.SerializeObject(values);
            propData.TextValue    = null;
            propData.IntegerValue = null;
            return(true);
        }
        private static void UpdateXmlTable(List <PropertyTypeDto> propertyTypes, PropertyDataDto data, List <ContentXmlDto> cmsContentXmlEntries, Database database)
        {
            //now we need to update the cmsContentXml table
            var propertyType = propertyTypes.SingleOrDefault(x => x.Id == data.PropertyTypeId);

            if (propertyType != null)
            {
                var xmlItem = cmsContentXmlEntries.SingleOrDefault(x => x.NodeId == data.NodeId);
                if (xmlItem != null)
                {
                    var x    = XElement.Parse(xmlItem.Xml);
                    var prop = x.Element(propertyType.Alias);
                    if (prop != null)
                    {
                        prop.ReplaceAll(new XCData(data.Text));
                        database.Update(xmlItem);
                    }
                }
            }
        }
        public void Issue8370Test()
        {
            // fixme maybe we need to create some content?
            // yes otherwise cannot get it to fail!

            var n = new NodeDto
            {
                Text       = "text",
                CreateDate = DateTime.Now,
                Path       = "-1",
                ParentId   = -1,
                UniqueId   = Guid.NewGuid()
            };

            DatabaseContext.Database.Insert(n);
            var ct = new ContentTypeDto
            {
                Alias     = "alias",
                NodeId    = n.NodeId,
                Thumbnail = "thumb"
            };

            DatabaseContext.Database.Insert(ct);
            n = new NodeDto
            {
                Text       = "text",
                CreateDate = DateTime.Now,
                Path       = "-1",
                ParentId   = -1,
                UniqueId   = Guid.NewGuid()
            };
            DatabaseContext.Database.Insert(n);
            var dt = new DataTypeDto
            {
                PropertyEditorAlias = Constants.PropertyEditors.RelatedLinksAlias,
                DbType     = "x",
                DataTypeId = n.NodeId
            };

            DatabaseContext.Database.Insert(dt);
            var pt = new PropertyTypeDto
            {
                Alias         = "alias",
                ContentTypeId = ct.NodeId,
                DataTypeId    = dt.DataTypeId
            };

            DatabaseContext.Database.Insert(pt);
            n = new NodeDto
            {
                Text       = "text",
                CreateDate = DateTime.Now,
                Path       = "-1",
                ParentId   = -1,
                UniqueId   = Guid.NewGuid()
            };
            DatabaseContext.Database.Insert(n);
            var data = new PropertyDataDto
            {
                NodeId         = n.NodeId,
                PropertyTypeId = pt.Id,
                Text           = "text",
                VersionId      = Guid.NewGuid()
            };

            DatabaseContext.Database.Insert(data);
            data = new PropertyDataDto
            {
                NodeId         = n.NodeId,
                PropertyTypeId = pt.Id,
                Text           = "<root><node title=\"\" type=\"\" newwindow=\"\" link=\"\" /></root>",
                VersionId      = Guid.NewGuid()
            };
            DatabaseContext.Database.Insert(data);

            var migration = new UpdateRelatedLinksData(SqlSyntax, Logger);

            migration.UpdateRelatedLinksDataDo(DatabaseContext.Database);

            data = DatabaseContext.Database.Fetch <PropertyDataDto>("SELECT * FROM cmsPropertyData WHERE id=" + data.Id).FirstOrDefault();
            Assert.IsNotNull(data);
            Debug.Print(data.Text);
            Assert.AreEqual("[{\"title\":\"\",\"caption\":\"\",\"link\":\"\",\"newWindow\":false,\"type\":\"external\",\"internal\":null,\"edit\":false,\"isInternal\":false}]",
                            data.Text);
        }
Beispiel #14
0
        protected IDictionary <int, PropertyCollection> GetPropertyCollection(
            Sql docSql,
            IEnumerable <DocumentDefinition> documentDefs)
        {
            if (documentDefs.Any() == false)
            {
                return(new Dictionary <int, PropertyCollection>());
            }

            //we need to parse the original SQL statement and reduce the columns to just cmsContent.nodeId, cmsContentVersion.VersionId so that we can use
            // the statement to go get the property data for all of the items by using an inner join
            var parsedOriginalSql = "SELECT {0} " + docSql.SQL.Substring(docSql.SQL.IndexOf("FROM", StringComparison.Ordinal));

            //now remove everything from an Orderby clause and beyond
            if (parsedOriginalSql.InvariantContains("ORDER BY "))
            {
                parsedOriginalSql = parsedOriginalSql.Substring(0, parsedOriginalSql.LastIndexOf("ORDER BY ", StringComparison.Ordinal));
            }

            var propSql = new Sql(@"SELECT cmsPropertyData.*
FROM cmsPropertyData
INNER JOIN cmsPropertyType
ON cmsPropertyData.propertytypeid = cmsPropertyType.id
INNER JOIN 
	("     + string.Format(parsedOriginalSql, "cmsContent.nodeId, cmsContentVersion.VersionId") + @") as docData
ON cmsPropertyData.versionId = docData.VersionId AND cmsPropertyData.contentNodeId = docData.nodeId
LEFT OUTER JOIN cmsDataTypePreValues
ON cmsPropertyType.dataTypeId = cmsDataTypePreValues.datatypeNodeId", docSql.Arguments);

            var allPropertyData = Database.Fetch <PropertyDataDto>(propSql);

            //This is a lazy access call to get all prevalue data for the data types that make up all of these properties which we use
            // below if any property requires tag support
            var allPreValues = new Lazy <IEnumerable <DataTypePreValueDto> >(() =>
            {
                var preValsSql = new Sql(@"SELECT a.id, a.value, a.sortorder, a.alias, a.datatypeNodeId
FROM cmsDataTypePreValues a
WHERE EXISTS(
    SELECT DISTINCT b.id as preValIdInner
    FROM cmsDataTypePreValues b
	INNER JOIN cmsPropertyType
	ON b.datatypeNodeId = cmsPropertyType.dataTypeId
    INNER JOIN 
	    ("     + string.Format(parsedOriginalSql, "DISTINCT cmsContent.contentType") + @") as docData
    ON cmsPropertyType.contentTypeId = docData.contentType
    WHERE a.id = b.id)", docSql.Arguments);

                return(Database.Fetch <DataTypePreValueDto>(preValsSql));
            });

            var result = new Dictionary <int, PropertyCollection>();

            var propertiesWithTagSupport = new Dictionary <string, SupportTagsAttribute>();

            //iterate each definition grouped by it's content type - this will mean less property type iterations while building
            // up the property collections
            foreach (var compositionGroup in documentDefs.GroupBy(x => x.Composition))
            {
                var compositionProperties = compositionGroup.Key.CompositionPropertyTypes.ToArray();

                foreach (var def in compositionGroup)
                {
                    var propertyDataDtos = allPropertyData.Where(x => x.NodeId == def.Id).Distinct();

                    var propertyFactory = new PropertyFactory(compositionProperties, def.Version, def.Id, def.CreateDate, def.VersionDate);
                    var properties      = propertyFactory.BuildEntity(propertyDataDtos.ToArray()).ToArray();

                    var newProperties = properties.Where(x => x.HasIdentity == false && x.PropertyType.HasIdentity);

                    foreach (var property in newProperties)
                    {
                        var propertyDataDto = new PropertyDataDto {
                            NodeId = def.Id, PropertyTypeId = property.PropertyTypeId, VersionId = def.Version
                        };
                        int primaryKey = Convert.ToInt32(Database.Insert(propertyDataDto));

                        property.Version = def.Version;
                        property.Id      = primaryKey;
                    }

                    foreach (var property in properties)
                    {
                        //NOTE: The benchmarks run with and without the following code show very little change so this is not a perf bottleneck
                        var editor = PropertyEditorResolver.Current.GetByAlias(property.PropertyType.PropertyEditorAlias);

                        var tagSupport = propertiesWithTagSupport.ContainsKey(property.PropertyType.PropertyEditorAlias)
                            ? propertiesWithTagSupport[property.PropertyType.PropertyEditorAlias]
                            : TagExtractor.GetAttribute(editor);

                        if (tagSupport != null)
                        {
                            //add to local cache so we don't need to reflect next time for this property editor alias
                            propertiesWithTagSupport[property.PropertyType.PropertyEditorAlias] = tagSupport;

                            //this property has tags, so we need to extract them and for that we need the prevals which we've already looked up
                            var preValData = allPreValues.Value.Where(x => x.DataTypeNodeId == property.PropertyType.DataTypeDefinitionId)
                                             .Distinct()
                                             .ToArray();

                            var asDictionary = preValData.ToDictionary(x => x.Alias, x => new PreValue(x.Id, x.Value, x.SortOrder));

                            var preVals = new PreValueCollection(asDictionary);

                            var contentPropData = new ContentPropertyData(property.Value,
                                                                          preVals,
                                                                          new Dictionary <string, object>());

                            TagExtractor.SetPropertyTags(property, contentPropData, property.Value, tagSupport);
                        }
                    }

                    if (result.ContainsKey(def.Id))
                    {
                        Logger.Warn <VersionableRepositoryBase <TId, TEntity> >("The query returned multiple property sets for document definition " + def.Id + ", " + def.Composition.Name);
                    }
                    result[def.Id] = new PropertyCollection(properties);
                }
            }

            return(result);
        }