/// <inheritdoc/>
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            var urlPickerPropertyData = JsonConvert.DeserializeObject <IEnumerable <UrlPickerPropertyData> >(value);

            foreach (var urlPicker in urlPickerPropertyData)
            {
                // When we set the value we want to switch the Guid value of the contentId/mediaId to the integervalue
                // as this is what the UrlPicker uses to lookup it's content/media
                int contentId;
                if (TryGetId(urlPicker.TypeData.ContentId, UmbracoObjectTypes.Document, out contentId))
                {
                    urlPicker.TypeData.ContentId = contentId;
                }

                // The picker can have values set for both content and media even though only one of them is "active".
                // We still need to resolve the value for both settings.
                int mediaId;
                if (TryGetId(urlPicker.TypeData.MediaId, UmbracoObjectTypes.Media, out mediaId))
                {
                    urlPicker.TypeData.MediaId = mediaId;
                }
            }

            content.SetValue(alias, JsonConvert.SerializeObject(urlPickerPropertyData));
        }
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }
            var links = JsonConvert.DeserializeObject <JArray>(value);

            if (links != null)
            {
                foreach (var link in links)
                {
                    GuidUdi udi;
                    string  url;
                    // Only do processing on an item if the Id or the url is set
                    if (TryParseJTokenAttr(link, "id", out udi))
                    {
                        // Check the type of the link
                        var nodeObjectType = link["isMedia"] != null
                            ? UmbracoObjectTypes.Media
                            : UmbracoObjectTypes.Document;

                        // Get the Id corresponding to the Guid
                        // it *should* succeed when deploying, due to dependencies management
                        // nevertheless, assume it can fail, and then create an invalid localLink
                        var idAttempt = _entityService.GetIdForKey(udi.Guid, nodeObjectType);
                        if (idAttempt)
                        {
                            link["id"] = idAttempt.Success ? idAttempt.Result : 0;
                        }
                    }
                    else if (TryParseJTokenAttr(link, "url", out url))
                    {
                        // Check weather the url attribut  of the link contains a udi, if so, replace it with the
                        // path to the file, i.e. the regex replaces <udi> with /path/to/file
                        var newUrl = MediaUdiSrcRegex.Replace(url, match =>
                        {
                            var udiString = match.Groups["udi"].ToString();
                            GuidUdi foundUdi;
                            if (GuidUdi.TryParse(udiString, out foundUdi) && foundUdi.EntityType == Constants.UdiEntityType.Media)
                            {
                                // (take care of nulls)
                                var media = _mediaService.GetById(foundUdi.Guid);
                                if (media != null)
                                {
                                    return(media.GetUrl("umbracoFile", _logger));
                                }
                            }
                            return(string.Empty);
                        });
                        link["url"] = newUrl;
                    }
                }
                content.SetValue(alias, JsonConvert.SerializeObject(links));
            }
        }
예제 #3
0
        /// <inheritdoc/>
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            IEnumerable <UrlPickerPropertyData> urlPickerPropertyDatas;

            // If using an old version of the UrlPicker - data is serialized as a single object
            // Otherwise data is serialized as an array of objects, even if only one is selected.
            if (UrlPickerVersion.Value < UrlPickerVersionStoringArray)
            {
                var urlPickerPropertyData = JsonConvert.DeserializeObject <UrlPickerPropertyData>(value);
                urlPickerPropertyDatas = new List <UrlPickerPropertyData> {
                    urlPickerPropertyData
                };
            }
            else
            {
                urlPickerPropertyDatas = JsonConvert.DeserializeObject <IEnumerable <UrlPickerPropertyData> >(value).ToList();
            }

            foreach (var urlPicker in urlPickerPropertyDatas)
            {
                // When we set the value we want to switch the Guid value of the contentId/mediaId to the integervalue
                // as this is what the UrlPicker uses to lookup it's content/media
                int contentId;
                if (TryGetId(urlPicker.TypeData.ContentId, UmbracoObjectTypes.Document, out contentId))
                {
                    urlPicker.TypeData.ContentId = contentId;
                }

                // The picker can have values set for both content and media even though only one of them is "active".
                // We still need to resolve the value for both settings.
                int mediaId;
                if (TryGetId(urlPicker.TypeData.MediaId, UmbracoObjectTypes.Media, out mediaId))
                {
                    urlPicker.TypeData.MediaId = mediaId;
                }
            }

            // If using an old version of the UrlPicker - data is serialized as a single object
            // Otherwise data is serialized as an array of objects, even if only one is selected.
            if (UrlPickerVersion.Value < UrlPickerVersionStoringArray)
            {
                content.SetValue(alias, JsonConvert.SerializeObject(urlPickerPropertyDatas.FirstOrDefault()));
            }
            else
            {
                content.SetValue(alias, JsonConvert.SerializeObject(urlPickerPropertyDatas));
            }
        }
예제 #4
0
        private async Task ImportFirstImageAsync(IContentBase postNode, BlogMLPost post)
        {
            var imageMimeTypes = new List <string> {
                "image/jpeg", "image/gif", "image/png"
            };

            var attachment = post.Attachments.FirstOrDefault(p => imageMimeTypes.Contains(p.MimeType));

            if (attachment == null)
            {
                return;
            }

            var imageSaved = false;

            if (!attachment.Content.IsNullOrWhiteSpace())
            {
                //the image is base64
                var bytes = Convert.FromBase64String(attachment.Content);
                using (var stream = new MemoryStream(bytes))
                {
                    postNode.SetValue(_contentTypeBaseServiceProvider, "postImage", attachment.Url.OriginalString, stream);
                    imageSaved = true;
                }
            }
            else if (attachment.ExternalUri != null && attachment.ExternalUri.IsAbsoluteUri)
            {
                try
                {
                    using (var client = new HttpClient())
                    {
                        using (var stream = await client.GetStreamAsync(attachment.ExternalUri))
                        {
                            postNode.SetValue(_contentTypeBaseServiceProvider, "postImage", Path.GetFileName(attachment.ExternalUri.AbsolutePath), stream);
                            imageSaved = true;
                        }
                    }
                }
                catch (Exception exception)
                {
                    _logger.Error <BlogMlImporter>(exception, "Exception retrieving {AttachmentUrl}; post {PostId}", attachment.Url, post.Id);
                }
            }

            if (imageSaved)
            {
                //this is a work around for the SetValue method to save a file, since it doesn't currently take into account the image cropper
                //which we are using so we need to fix that.

                var propType     = postNode.Properties["postImage"].PropertyType;
                var cropperValue = CreateImageCropperValue(propType, postNode.GetValue("postImage"), _dataTypeService);
                postNode.SetValue("postImage", cropperValue);
            }
        }
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            var relatedLinks = JsonConvert.DeserializeObject <JArray>(value);

            foreach (var relatedLink in relatedLinks)
            {
                //Get the value from the JSON object
                var isInternal = Convert.ToBoolean(relatedLink["isInternal"]);

                //We are only concerned about internal links
                if (!isInternal)
                {
                    continue;
                }

                var relatedLinkValue = relatedLink["link"].ToString();

                //Check if related links is stored as an int
                if (int.TryParse(relatedLinkValue, out var relatedLinkInt))
                {
                    //Update the JSON back to the int ids on this env
                    relatedLink["link"]     = relatedLinkInt;
                    relatedLink["internal"] = relatedLinkInt;
                }
                else
                {
                    //Get the UDI value in the JSON
                    var pickedUdi = GuidUdi.Parse(relatedLinkValue);

                    //Lets use entitiy sevice to get the int ID for this item on the new environment
                    //Get the Id corresponding to the Guid
                    //it *should* succeed when deploying, due to dependencies management
                    //nevertheless, assume it can fail, and then create an invalid localLink
                    var idAttempt = _entityService.GetIdForKey(pickedUdi.Guid, UmbracoObjectTypes.Document);

                    //Update the JSON back to the int ids on this env
                    relatedLink["link"]     = idAttempt.Success ? idAttempt.Result : 0;
                    relatedLink["internal"] = idAttempt.Success ? idAttempt.Result : 0;
                }
            }

            //Save the updated JSON with replaced UDIs for int IDs
            content.SetValue(alias, JsonConvert.SerializeObject(relatedLinks));
        }
        protected void SetPropertyOnContent(IContentBase content, PropertyRegistration property, object propertyValue)
        {
            object convertedValue;

            if (property.DataType.ConverterType != null)
            {
                object toConvert;
                var    attr = property.Metadata.GetCodeFirstAttribute <ContentPropertyAttribute>();

                if (attr != null && attr is IDataTypeRedirect)
                {
                    toConvert = (attr as IDataTypeRedirect).GetOriginalDataTypeObject(propertyValue);
                }
                else
                {
                    toConvert = propertyValue;
                }

                IDataTypeConverter converter = (IDataTypeConverter)Activator.CreateInstance(property.DataType.ConverterType);
                convertedValue = converter.Serialise(toConvert);
            }
            else if (!property.DataType.CodeFirstControlled && property.DataType.DbType == DatabaseType.None)
            {
                throw new CodeFirstException("Cannot persist PEVC-based properties or use events which attempt to persist PEVC-based properties. " + Environment.NewLine +
                                             "PEVCs only support retrieving a value from IPublishedContent & cannot persist a property back to IContent." + Environment.NewLine +
                                             "Property: " + property.Metadata.DeclaringType.FullName + "." + property.Name);
            }
            else
            {
                //No converter is given so we push the value back into umbraco as is (this will fail in many cases for PEVC properties)
                convertedValue = propertyValue;
            }

            content.SetValue(property.Alias, convertedValue);
        }
예제 #7
0
        private async Task ImportFirstImageAsync(IContentBase postNode, BlogMLPost post)
        {
            var imageMimeTypes = new List <string> {
                "image/jpeg", "image/gif", "image/png"
            };

            var attachment = post.Attachments.FirstOrDefault(p => imageMimeTypes.Contains(p.MimeType));

            if (attachment == null)
            {
                return;
            }
            var path = attachment.Url.GetPath();

            try
            {
                using (var client = new HttpClient())
                {
                    using (var stream = await client.GetStreamAsync(attachment.Url))
                    {
                        postNode.SetValue("postImage", Path.GetFileName(path), stream);
                    }
                }
            }
            catch (Exception exception)
            {
                LogHelper.Error <BlogMlImporter>($"Exception retrieving {attachment.Url}; post {post.Id}", exception);
            }
        }
예제 #8
0
        private static void SetReservationStatus(IContentBase apartment, string valueName)
        {
            var dts          = new DataTypeService();
            var statusEditor = dts.GetAllDataTypeDefinitions().First(x => x.Name == "Status Rezerwacji");
            var preValueId   = dts.GetPreValuesCollectionByDataTypeId(statusEditor.Id).PreValuesAsDictionary.Where(d => d.Value.Value == valueName).Select(f => f.Value.Id).First();

            apartment.SetValue("status", preValueId);
        }
예제 #9
0
        private static void SetPropertyValue(IContentBase content, XmlNode uploadFieldConfigNode, string propertyAlias, string propertyValue)
        {
            XmlNode propertyNode = uploadFieldConfigNode.SelectSingleNode(propertyAlias);

            if (propertyNode != null && string.IsNullOrEmpty(propertyNode.FirstChild.Value) == false && content.HasProperty(propertyNode.FirstChild.Value))
            {
                content.SetValue(propertyNode.FirstChild.Value, propertyValue);
            }
        }
예제 #10
0
        /// <summary>
        /// Sets all invariant or variant property values safely while taking into account the variance settings on the content type/property type
        /// </summary>
        /// <param name="content">The content to set the values for</param>
        /// <param name="propertyAlias">The property alias to set the values for</param>
        /// <param name="propertyValueGetter">Callback to get the value to be set for the given culture</param>
        /// <remarks>
        /// This will only set property values for cultures that have been defined on the <see cref="IContentBase"/>, it will
        /// not set property values for cultures that don't yet exist on the content item.
        /// </remarks>
        public static void SetAllPropertyCultureValues(
            this IContentBase content,
            string propertyAlias,
            IContentTypeComposition contentType,
            Func <IContentBase, IContentTypeComposition, ContentCultureInfos, object> propertyValueGetter)
        {
            if (contentType is null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            if (content.ContentType.VariesByCulture())
            {
                // iterate over any existing cultures defined on the content item
                foreach (var c in content.CultureInfos)
                {
                    var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == propertyAlias);
                    if (propertyType == null)
                    {
                        throw new InvalidOperationException($"No property type found by alias {propertyAlias}");
                    }

                    var valueToSet = propertyValueGetter(content, contentType, c);
                    if (valueToSet == null || (valueToSet is string propValAsString && string.IsNullOrWhiteSpace(propValAsString)))
                    {
                        continue;
                    }

                    content.SetValue(propertyAlias, valueToSet, propertyType.VariesByCulture() ? c.Culture : null);
                }
            }
            else
            {
                var propertyValue = propertyValueGetter(content, contentType, null);
                if (propertyValue == null || (propertyValue is string propValAsString && string.IsNullOrWhiteSpace(propValAsString)))
                {
                    return;
                }

                content.SetValue(propertyAlias, propertyValue);
            }
        }
예제 #11
0
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (String.IsNullOrWhiteSpace(value))
            {
                // Save empty value
                content.SetValue(alias, value);
                return;
            }

            if (!StringExtensions.DetectIsJson(value))
            {
                // Skip invalid values
                return;
            }

            // Parse links and convert UDI back to local ID
            var rootLinks = ParseLinks(JArray.Parse(value), null, Direction.FromArtifact);

            content.SetValue(alias, rootLinks.ToString(Formatting.None));
        }
예제 #12
0
 public static void SetDropDownListValue(this IContentBase content, string aliasName, string dropValue)
 {
     try
     {
         var value = ((IContent)content).GetPropertyByAlias(aliasName).GetPreValue().GetPreValueIdByValue(dropValue);
         content.SetValue(aliasName, value);
     }
     catch
     {
     }
 }
예제 #13
0
        public void SetValue(IContentBase content, string alias, string value)
        {
            // take the value
            if (string.IsNullOrWhiteSpace(value))
            {
                return;
            }

            // deserialize it
            var model = JsonConvert.DeserializeObject <PropertyListValue>(value);

            if (model == null)
            {
                return;
            }

            // get the selected data-type (and ensure it exists)
            var dataType = _dataTypeService.GetDataTypeDefinitionById(model.DataTypeGuid);

            if (dataType == null)
            {
                throw new InvalidOperationException($"Could not resolve the data-type used by the Property List value for: {alias}");
            }

            // make a property-type to use in a mocked Property
            // and get the value-connector needed to parse values (outside the loop, as it's the same for all iterations)
            var propertyType   = new PropertyType(dataType, "mockPropertyListAlias");
            var valueConnector = ValueConnectors.Get(propertyType);

            // loop through each value
            for (int i = 0; i < model.Values.Count; i++)
            {
                var item = model.Values[i];

                var mockProperty = new Property(propertyType);
                var mockContent  = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> {
                    mockProperty
                }));

                // pass it to its own value-connector
                // NOTE: due to how ValueConnector.SetValue() works, we have to pass the mock item
                // through to the connector to have it do its work on parsing the value on the item itself.
                valueConnector.SetValue(mockContent, mockProperty.Alias, item?.ToString());

                // get the value back and assign
                model.Values[i] = mockContent.GetValue(mockProperty.Alias);
            }

            // serialize the JSON values
            content.SetValue(alias, JObject.FromObject(model).ToString(Formatting.None));
        }
        public void SetValue(IContentBase content, string alias, string value)
        {
            // take the value
            if (string.IsNullOrWhiteSpace(value))
            {
                return;
            }

            // deserialize it
            var items = JsonConvert.DeserializeObject <List <TupleValueItem> >(value);

            if (items == null || items.Count == 0)
            {
                return;
            }

            // loop through each value
            foreach (var item in items)
            {
                // get the selected data-type (and ensure it exists)
                var dataType = _dataTypeService.GetDataTypeDefinitionById(item.DataTypeGuid);

                if (dataType == null)
                {
                    LogHelper.Warn <TupleValueConnector>($"Could not resolve the data-type used by the Tuple item for: {alias}, with GUID: {item.DataTypeGuid}");
                    continue;
                }

                // make a property-type to use in a mocked Property
                // and get the value-connector needed to parse values (outside the loop, as it's the same for all iterations)
                var propertyType   = new PropertyType(dataType, "mockTupleAlias");
                var valueConnector = ValueConnectors.Get(propertyType);

                var mockProperty = new Property(propertyType);
                var mockContent  = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> {
                    mockProperty
                }));

                // pass it to its own value-connector
                // NOTE: due to how ValueConnector.SetValue() works, we have to pass the mock item
                // through to the connector to have it do its work on parsing the value on the item itself.
                valueConnector.SetValue(mockContent, mockProperty.Alias, item.Value?.ToString());

                // get the value back and assign
                item.Value = mockContent.GetValue(mockProperty.Alias);
            }

            // serialize the JSON values
            content.SetValue(alias, JArray.FromObject(items).ToString(Formatting.None));
        }
예제 #15
0
        /// <summary>
        ///  second pass ID update in properties?
        /// </summary>
        /// <param name="node"></param>
        /// <param name="item"></param>
        public void DeserializeMappedIds(T baseItem, XElement node)
        {
            IContentBase item       = (IContentBase)baseItem;
            var          properties = node.Elements().Where(x => x.Attribute("isDoc") == null);

            foreach (var property in properties)
            {
                var propertyTypeAlias = property.Name.LocalName;
                if (item.HasProperty(propertyTypeAlias))
                {
                    var    prop     = item.Properties[propertyTypeAlias];
                    string newValue = GetImportIds(prop.PropertyType, GetImportXml(property));
                    LogHelper.Debug <Events>("#### BASE: Setting property: [{0}] to {1}", () => propertyTypeAlias, () => newValue);
                    item.SetValue(propertyTypeAlias, newValue);
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Sets the value for a property type with the correct variance
        /// </summary>
        /// <remarks>
        /// Used to safely set a value for a property taking into account if the property type varies by culture/segment.
        /// If varying by culture it will assign the value to the default language only.
        /// If varying by segment it will assign the value to no segment.
        /// </remarks>
        public static void SetInvariantOrDefaultCultureValue(
            this IContentBase content,
            string propertyTypeAlias,
            object value,
            IContentTypeComposition contentType,
            ILocalizationService localizationService)
        {
            if (contentType is null)
            {
                throw new ArgumentNullException(nameof(contentType));
            }

            var variesByCulture = VariesByCulture(propertyTypeAlias, contentType);

            content.SetValue(
                propertyTypeAlias,
                value,
                variesByCulture ? localizationService.GetDefaultLanguageIsoCode() : null);
        }
예제 #17
0
        /// <summary>
        /// Sets the default value.
        /// </summary>
        /// <param name="content">The content to set default values for.</param>
        /// <param name="model">The model.</param>
        private static void SetDefaultValue(IContentBase content, PropertyType model)
        {
            if (!model.HasDefaultValue)
            {
                return;
            }

            var value = content.GetValue(model.Alias);

            if (value != null)
            {
                return;
            }

            if (!CanSetDefaultValue(model.Type, model.DefaultValue))
            {
                return;
            }

            content.SetValue(model.Alias, model.DefaultValue);
        }
예제 #18
0
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        public void SetValue(IContentBase content, string alias, string value)
        {
            // parse the value - checking the format - CSV, XML or JSON
            SaveFormat format;
            var        items = ParseValue(value, out format);

            var result = new List <KeyValuePair <string, string> >();

            // loop over the values
            foreach (var item in items)
            {
                GuidUdi guidUdi;
                if (GuidUdi.TryParse(item.Key, out guidUdi) && guidUdi.Guid != Guid.Empty)
                {
                    // if an UDI, attempt to get the INT
                    var nodeId = GetIntId(guidUdi.Guid);
                    if (nodeId > 0)
                    {
                        result.Add(new KeyValuePair <string, string>(nodeId.ToString(), item.Value));
                    }
                    else
                    {
                        // the value isn't a node ID, assume it's "just a string"
                        result.Add(item);
                    }
                }
                else
                {
                    // the value isn't a UDI, assume it's "just a string"
                    result.Add(item);
                }
            }

            // re-assemble the values into the correct format - CSV, XML, JSON, (whatevs)
            content.SetValue(alias, SerializeValue(result, format));
        }
예제 #19
0
 private static void SetPropertyValue(IContentBase content, XmlNode uploadFieldConfigNode, string propertyAlias, string propertyValue)
 {
     XmlNode propertyNode = uploadFieldConfigNode.SelectSingleNode(propertyAlias);
     if (propertyNode != null && string.IsNullOrEmpty(propertyNode.FirstChild.Value) == false && content.HasProperty(propertyNode.FirstChild.Value))
     {
         content.SetValue(propertyNode.FirstChild.Value, propertyValue);
     }
 }
예제 #20
0
        private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string filename, Stream fileStream)
        {
            var property = content.Properties.FirstOrDefault(x => x.Alias == propertyTypeAlias);
            if (property == null)
                return;

            //TODO: ALl of this naming logic needs to be put into the ImageHelper and then we need to change FileUploadPropertyValueEditor to do the same!

            var numberedFolder = MediaSubfolderCounter.Current.Increment();
            var fileName = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                              ? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), filename)
                                              : numberedFolder + "-" + filename;

            var extension = Path.GetExtension(filename).Substring(1).ToLowerInvariant();

            //the file size is the length of the stream in bytes
            var fileSize = fileStream.Length;

            var fs = FileSystemProviderManager.Current.GetFileSystemProvider<MediaFileSystem>();
            fs.AddFile(fileName, fileStream);

            //Check if file supports resizing and create thumbnails
            var supportsResizing = UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.InvariantContains(extension);

            //the config section used to auto-fill properties
            IImagingAutoFillUploadField uploadFieldConfigNode = null;

            //Check for auto fill of additional properties
            if (UmbracoConfig.For.UmbracoSettings().Content.ImageAutoFillProperties != null)
            {
                uploadFieldConfigNode = UmbracoConfig.For.UmbracoSettings().Content.ImageAutoFillProperties
                                    .FirstOrDefault(x => x.Alias == propertyTypeAlias);

            }

            if (supportsResizing)
            {
                //get the original image from the original stream
                if (fileStream.CanSeek) fileStream.Seek(0, 0);
                using (var originalImage = Image.FromStream(fileStream))
                {
                    var additionalSizes = new List<int>();

                    //Look up Prevalues for this upload datatype - if it is an upload datatype - get additional configured sizes
                    if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)
                    {
                        //Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
                        var values = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId);
                        var thumbnailSizes = values.FirstOrDefault();
                        //Additional thumbnails configured as prevalues on the DataType
                        if (thumbnailSizes != null)
                        {
                            var sep = (thumbnailSizes.Contains("") == false && thumbnailSizes.Contains(",")) ? ',' : ';';
                            foreach (var thumb in thumbnailSizes.Split(sep))
                            {
                                int thumbSize;
                                if (thumb != "" && int.TryParse(thumb, out thumbSize))
                                {
                                    additionalSizes.Add(thumbSize);
                                }
                            }
                        }
                    }

                    ImageHelper.GenerateMediaThumbnails(fs, fileName, extension, originalImage, additionalSizes);

                    //while the image is still open, we'll check if we need to auto-populate the image properties
                    if (uploadFieldConfigNode != null)
                    {
                        content.SetValue(uploadFieldConfigNode.WidthFieldAlias, originalImage.Width.ToString(CultureInfo.InvariantCulture));
                        content.SetValue(uploadFieldConfigNode.HeightFieldAlias, originalImage.Height.ToString(CultureInfo.InvariantCulture));
                    }

                }
            }

            //if auto-fill is true, then fill the remaining, non-image properties
            if (uploadFieldConfigNode != null)
            {
                content.SetValue(uploadFieldConfigNode.LengthFieldAlias, fileSize.ToString(CultureInfo.InvariantCulture));
                content.SetValue(uploadFieldConfigNode.ExtensionFieldAlias, extension);
            }

            //Set the value of the property to that of the uploaded file's url
            property.Value = fs.GetUrl(fileName);
        }
예제 #21
0
 /// <summary>
 /// Sets the posted file value of a property.
 /// </summary>
 public static void SetValue(this IContentBase content, IContentTypeBaseServiceProvider contentTypeBaseServiceProvider, string propertyTypeAlias, string filename, HttpPostedFileBase postedFile, string culture = null, string segment = null)
 {
     content.SetValue(contentTypeBaseServiceProvider, propertyTypeAlias, postedFile.FileName, postedFile.InputStream, culture, segment);
 }
예제 #22
0
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            if (value.DetectIsJson() == false)
            {
                return;
            }

            var property = content.Properties[alias];

            if (property == null)
            {
                throw new NullReferenceException($"Property not found: '{alias}'.");
            }

            var prevalues = _dataTypeService.GetPreValuesCollectionByDataTypeId(property.PropertyType.DataTypeDefinitionId).FormatAsDictionary();

            PreValue prevalue = null;

            //Fetch the Prevalues for the current Property's DataType (if its an 'Archetype config')
            if (!prevalues.TryGetValue("archetypeconfig", out prevalue) && !prevalues.TryGetValue("archetypeConfig", out prevalue))
            {
                throw new InvalidOperationException("Could not find Archetype configuration.");
            }
            var archetypePreValue = prevalue == null
                ? null
                : JsonConvert.DeserializeObject <ArchetypePreValue>(prevalue.Value);

            RetrieveAdditionalProperties(ref archetypePreValue);

            var archetype = JsonConvert.DeserializeObject <ArchetypeModel>(value);

            if (archetype == null)
            {
                throw new InvalidOperationException("Could not parse Archetype value.");
            }

            RetrieveAdditionalProperties(ref archetype, archetypePreValue);

            var properties = archetype.Fieldsets.SelectMany(x => x.Properties);

            foreach (var archetypeProperty in properties)
            {
                if (archetypeProperty.Value == null || string.IsNullOrEmpty(archetypeProperty.DataTypeGuid))
                {
                    continue;
                }

                // get the data type of the property
                var dataType = _dataTypeService.GetDataTypeDefinitionById(Guid.Parse(archetypeProperty.DataTypeGuid));
                if (dataType == null)
                {
                    throw new ArgumentNullException(
                              $"Unable to find the data type for editor '{archetypeProperty.PropertyEditorAlias}' ({archetypeProperty.DataTypeGuid}) referenced by '{property.Alias}'.");
                }

                // try to convert the value with the macro parser - this is mainly for legacy editors
                var archetypeValue = _macroParser.ReplaceAttributeValue(archetypeProperty.Value.ToString(), dataType.PropertyEditorAlias, null, Direction.FromArtifact);

                Udi udi;
                // test if the macroparser converted the value to an Udi
                if (Udi.TryParse(archetypeValue, out udi))
                {
                    archetypeProperty.Value = archetypeValue;
                    continue;
                }

                // if the macro parser didn't convert the value then try to find a value connector that can and convert it
                var propertyType = new PropertyType(dataType.PropertyEditorAlias, dataType.DatabaseType, "mockPropertyTypeAlias");
                propertyType.DataTypeDefinitionId = dataType.Id;
                var propValueConnector = ValueConnectors.Get(propertyType);
                var mockProperty       = new Property(propertyType);
                var mockContent        = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> {
                    mockProperty
                }));
                propValueConnector.SetValue(mockContent, mockProperty.Alias, archetypeProperty.Value.ToString());
                archetypeProperty.Value = mockContent.GetValue(mockProperty.Alias);
            }
            value = archetype.SerializeForPersistence();
            content.SetValue(alias, value);
        }
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        /// <remarks>
        /// This is a bit tricky because for each cell of nested content we need to pass the value of it to it's related
        /// IValueConnector because each cell is essentially a Property Type - though a fake one.
        /// So to do this we have to create a fake content item for the underlying IValueConnector to set it's value on and
        /// then we can extract that value from it to put on the main serialized object to set on the real IContentBase item.
        /// </remarks>
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            if (value.DetectIsJson() == false)
            {
                return;
            }

            var nestedContent = JsonConvert.DeserializeObject <NestedContentValue[]>(value);

            if (nestedContent == null)
            {
                return;
            }

            var allContentTypes = nestedContent.Select(x => x.ContentTypeAlias)
                                  .Distinct()
                                  .ToDictionary(a => a, a => _contentTypeService.GetContentType(a));

            //Ensure all of these content types are found
            if (allContentTypes.Values.Any(contentType => contentType == null))
            {
                throw new InvalidOperationException($"Could not resolve these content types for the Nested Content property: {string.Join(",", allContentTypes.Where(x => x.Value == null).Select(x => x.Key))}");
            }

            var mocks = new Dictionary <IContentType, IContent>();

            foreach (var row in nestedContent)
            {
                var contentType = allContentTypes[row.ContentTypeAlias];

                // note
                // the way we do it here, doing content.SetValue() several time on the same content, reduces
                // allocations and should be ok because SetValue does not care about the previous value - would
                // be different for the overloads that manage eg files for uploads (not sure how NestedContent
                // deals with them really)

                // we need a fake content instance to pass in to the value connector, since the value connector
                // wants to SetValue on an object - then we can extract the value back from that object to set
                // it correctly on the real instance
                IContent mockContent;
                if (!mocks.TryGetValue(contentType, out mockContent))
                {
                    mockContent = mocks[contentType] = new Content("NC_" + Guid.NewGuid(), -1, contentType);
                }

                foreach (var key in row.PropertyValues.Keys.ToArray())
                {
                    // key is a system property that is added by NestedContent in Core v7.7
                    // see note in NestedContentValue - leave it unchanged
                    if (key == "key")
                    {
                        continue;
                    }

                    var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == key);

                    if (propertyType == null)
                    {
                        LogHelper.Debug <NestedContentValueConnector>($"No Property Type found with alias {key} on Content Type {contentType.Alias}");
                        continue;
                    }

                    // throws if not found - no need for a null check
                    var propValueConnector = ValueConnectors.Get(propertyType);

                    var rowValue = row.PropertyValues[key];

                    if (rowValue != null)
                    {
                        propValueConnector.SetValue(mockContent, propertyType.Alias, rowValue.ToString());
                        var convertedValue = mockContent.GetValue(propertyType.Alias);
                        if (convertedValue == null)
                        {
                            row.PropertyValues[key] = null;
                        }
                        // integers needs to be converted into strings
                        else if (convertedValue is int)
                        {
                            row.PropertyValues[key] = convertedValue.ToString();
                        }
                        else
                        {
                            // test if the value is a json object (thus could be a nested complex editor)
                            // if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
                            JToken jtokenValue = convertedValue.ToString().DetectIsJson() ? JToken.Parse(convertedValue.ToString()) : null;
                            if (jtokenValue != null)
                            {
                                row.PropertyValues[key] = jtokenValue;
                            }
                            else
                            {
                                row.PropertyValues[key] = convertedValue;
                            }
                        }
                    }
                    else
                    {
                        row.PropertyValues[key] = rowValue;
                    }
                }
            }

            // NestedContent does not use formatting when serializing JSON values
            if (nestedContent.Length == 1)
            {
                value = JObject.FromObject(nestedContent.FirstOrDefault()).ToString(Formatting.None);
            }
            else
            {
                value = JArray.FromObject(nestedContent).ToString(Formatting.None);
            }

            content.SetValue(alias, value);
        }
예제 #24
0
 public void SetValue(IContentBase content, string alias, string value)
 {
     //Save the JSON on the env we are deploying to
     //We don't need to swap UDIs out back for int's so a simple setValue is all we need
     content.SetValue(alias, value);
 }
예제 #25
0
        private static void SetFileOnContent(IContentBase content, string propertyTypeAlias, string filename, Stream fileStream)
        {
            var property = content.Properties.FirstOrDefault(x => x.Alias == propertyTypeAlias);

            if (property == null)
            {
                return;
            }

            //TODO: ALl of this naming logic needs to be put into the ImageHelper and then we need to change FileUploadPropertyValueEditor to do the same!

            var numberedFolder = MediaSubfolderCounter.Current.Increment();
            var fileName       = UmbracoConfig.For.UmbracoSettings().Content.UploadAllowDirectories
                                              ? Path.Combine(numberedFolder.ToString(CultureInfo.InvariantCulture), filename)
                                              : numberedFolder + "-" + filename;

            var extension = Path.GetExtension(filename).Substring(1).ToLowerInvariant();

            //the file size is the length of the stream in bytes
            var fileSize = fileStream.Length;

            var fs = FileSystemProviderManager.Current.GetFileSystemProvider <MediaFileSystem>();

            fs.AddFile(fileName, fileStream);

            //Check if file supports resizing and create thumbnails
            var supportsResizing = UmbracoConfig.For.UmbracoSettings().Content.ImageFileTypes.InvariantContains(extension);

            //the config section used to auto-fill properties
            IImagingAutoFillUploadField uploadFieldConfigNode = null;

            //Check for auto fill of additional properties
            if (UmbracoConfig.For.UmbracoSettings().Content.ImageAutoFillProperties != null)
            {
                uploadFieldConfigNode = UmbracoConfig.For.UmbracoSettings().Content.ImageAutoFillProperties
                                        .FirstOrDefault(x => x.Alias == propertyTypeAlias);
            }

            if (supportsResizing)
            {
                //get the original image from the original stream
                if (fileStream.CanSeek)
                {
                    fileStream.Seek(0, 0);
                }
                using (var originalImage = Image.FromStream(fileStream))
                {
                    var additionalSizes = new List <int>();

                    //Look up Prevalues for this upload datatype - if it is an upload datatype - get additional configured sizes
                    if (property.PropertyType.PropertyEditorAlias == Constants.PropertyEditors.UploadFieldAlias)
                    {
                        //Get Prevalues by the DataType's Id: property.PropertyType.DataTypeId
                        var values         = ApplicationContext.Current.Services.DataTypeService.GetPreValuesByDataTypeId(property.PropertyType.DataTypeDefinitionId);
                        var thumbnailSizes = values.FirstOrDefault();
                        //Additional thumbnails configured as prevalues on the DataType
                        if (thumbnailSizes != null)
                        {
                            foreach (var thumb in thumbnailSizes.Split(new[] { ";", "," }, StringSplitOptions.RemoveEmptyEntries))
                            {
                                int thumbSize;
                                if (thumb != "" && int.TryParse(thumb, out thumbSize))
                                {
                                    additionalSizes.Add(thumbSize);
                                }
                            }
                        }
                    }

                    ImageHelper.GenerateMediaThumbnails(fs, fileName, extension, originalImage, additionalSizes);

                    //while the image is still open, we'll check if we need to auto-populate the image properties
                    if (uploadFieldConfigNode != null)
                    {
                        content.SetValue(uploadFieldConfigNode.WidthFieldAlias, originalImage.Width.ToString(CultureInfo.InvariantCulture));
                        content.SetValue(uploadFieldConfigNode.HeightFieldAlias, originalImage.Height.ToString(CultureInfo.InvariantCulture));
                    }
                }
            }

            //if auto-fill is true, then fill the remaining, non-image properties
            if (uploadFieldConfigNode != null)
            {
                content.SetValue(uploadFieldConfigNode.LengthFieldAlias, fileSize.ToString(CultureInfo.InvariantCulture));
                content.SetValue(uploadFieldConfigNode.ExtensionFieldAlias, extension);
            }

            //Set the value of the property to that of the uploaded file's url
            property.Value = fs.GetUrl(fileName);
        }
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        /// <remarks>
        /// This will loop through all the values stored inside the Vorto property, using the IValueConnector to parse each value.
        /// Due to how the ValueConnectors set the value, we have to create mocked content items and assign the value to it.
        /// Then the mock item is passed to the ValueConnector, matching the property type being wrapped by Vorto and the
        /// ValueConnector will parse the value.
        /// When the ValueConnector has done its work, the parsed value is extracted from the mock content and then assigned back
        /// to the original field inside the Vorto value object instead.
        /// </remarks>
        public void SetValue(IContentBase content, string alias, string value)
        {
            // if there's an empty value we don't need to do more work
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            // fail fast if this isn't JSON
            if (value.DetectIsJson() == false)
            {
                return;
            }

            // try parsing this as a Vorto value
            var vortoValue = JsonConvert.DeserializeObject <VortoValue>(value);

            if (vortoValue == null)
            {
                return;
            }

            // getting the wrapped datatype via the Vorto datatype
            var vortoDataType             = _dataTypeService.GetDataTypeDefinitionById(Guid.Parse(vortoValue.DtdGuid));
            var vortoDataTypePrevalueJson = _dataTypeService.GetPreValuesCollectionByDataTypeId(vortoDataType.Id).FormatAsDictionary().FirstOrDefault(x => x.Key == "dataType").Value.Value;
            var vortoDataTypePrevalue     = JsonConvert.DeserializeObject <VortoDatatypePrevalue>(vortoDataTypePrevalueJson);

            var wrappedDataType = _dataTypeService.GetDataTypeDefinitionById(vortoDataTypePrevalue.Guid);

            // ensure the wrapped datatype is found
            if (wrappedDataType == null)
            {
                throw new InvalidOperationException($"Could not resolve the datatype used inside the Vorto property: {alias}");
            }

            var propertyType   = new PropertyType(wrappedDataType, "mockPropertyType");
            var valueConnector = ValueConnectors.Get(propertyType);

            // iterate values for each language
            foreach (var languageKey in vortoValue.Values.ValuePairs.Keys.ToArray())
            {
                var val = vortoValue.Values.ValuePairs[languageKey];

                var mockProperty = new Property(propertyType, val);
                var mockContent  = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> {
                    mockProperty
                }));

                // due to how ValueConnector.SetValue() works, we have to pass the mock item through the connector to have it do its
                // work on parsing the value on the item itself.
                valueConnector.SetValue(mockContent, mockProperty.Alias, val.ToString());

                // we then extract the converted value from the mock item so we can assign it to the inner value object inside the
                // actual Vorto item's value pair for this specific language.
                var convertedValue = mockContent.GetValue(mockProperty.Alias);

                var jtokenValue = convertedValue != null && convertedValue.ToString().DetectIsJson() ? JToken.Parse(convertedValue.ToString()) : null;
                if (jtokenValue != null)
                {
                    convertedValue = jtokenValue;
                }
                else if (convertedValue != null)
                {
                    convertedValue = convertedValue.ToString();
                }
                vortoValue.Values.ValuePairs[languageKey] = convertedValue;
            }

            // Vorto does not use formatting when serializing JSON values
            value = JObject.FromObject(vortoValue).ToString(Formatting.None);
            content.SetValue(alias, value);
        }
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        /// <remarks>
        /// This is a bit tricky because for each row of inner content we need to pass the value of it to it's related
        /// IValueConnector because each row is essentially a Property Type - though a fake one.
        /// So to do this we have to create a fake content item for the underlying IValueConnector to set it's value on and
        /// then we can extract that value from it to put on the main serialized object to set on the real IContentBase item.
        /// </remarks>
        public void SetValue(IContentBase content, string alias, string value)
        {
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            if (value.DetectIsJson() == false)
            {
                return;
            }

            var innerContent = JsonConvert.DeserializeObject <InnerContentValue[]>(value);

            if (innerContent == null)
            {
                return;
            }

            foreach (var innerContentItem in innerContent)
            {
                IContentType contentType = null;
                if (innerContentItem.IcContentTypeGuid.HasValue)
                {
                    contentType = _contentTypeService.GetContentType(innerContentItem.IcContentTypeGuid.Value);
                }
                if (contentType == null)
                {
                    contentType = _contentTypeService.GetContentType(innerContentItem.IcContentTypeAlias);
                }
                if (contentType == null)
                {
                    throw new InvalidOperationException($"Could not resolve these content types for the Inner Content property with key: {innerContentItem.Key}, and name: {innerContentItem.Name}");
                }

                var mocks = new Dictionary <IContentType, IContent>();

                // note
                // the way we do it here, doing content.SetValue() several time on the same content, reduces
                // allocations and should be ok because SetValue does not care about the previous value - would
                // be different for the overloads that manage eg files for uploads (not sure how NestedContent
                // deals with them really)

                // we need a fake content instance to pass in to the value connector, since the value connector
                // wants to SetValue on an object - then we can extract the value back from that object to set
                // it correctly on the real instance
                IContent mockContent;
                if (!mocks.TryGetValue(contentType, out mockContent))
                {
                    mockContent = mocks[contentType] = new Content("IC_" + Guid.NewGuid(), -1, contentType);
                }

                if (innerContentItem.PropertyValues != null)
                {
                    foreach (var key in innerContentItem.PropertyValues.Keys.ToArray())
                    {
                        var propertyType = contentType.CompositionPropertyTypes.FirstOrDefault(x => x.Alias == key);

                        if (propertyType == null)
                        {
                            LogHelper.Debug <InnerContentConnector>($"No Property Type found with alias {key} on Content Type {contentType.Alias}");
                            continue;
                        }

                        // throws if not found - no need for a null check
                        var propValueConnector = ValueConnectors.Get(propertyType);

                        var rowValue = innerContentItem.PropertyValues[key];

                        if (rowValue != null)
                        {
                            propValueConnector.SetValue(mockContent, propertyType.Alias, rowValue.ToString());
                            var convertedValue = mockContent.GetValue(propertyType.Alias);
                            // integers needs to be converted into strings
                            if (convertedValue is int)
                            {
                                innerContentItem.PropertyValues[key] = convertedValue.ToString();
                            }
                            else
                            {
                                // test if the value is a json object (thus could be a nested complex editor)
                                // if that's the case we'll need to add it as a json object instead of string to avoid it being escaped
                                JToken jtokenValue;
                                if (TryParseJToken(convertedValue, out jtokenValue))
                                {
                                    innerContentItem.PropertyValues[key] = jtokenValue;
                                }
                                else
                                {
                                    innerContentItem.PropertyValues[key] = convertedValue;
                                }
                            }
                        }
                        else
                        {
                            innerContentItem.PropertyValues[key] = rowValue;
                        }
                    }
                }
            }

            // InnerContent does not use formatting when serializing JSON values
            value = JArray.FromObject(innerContent).ToString(Formatting.None);
            content.SetValue(alias, value);
        }
        /// <summary>
        /// Sets a content property value using a deploy property.
        /// </summary>
        /// <param name="content">The content item.</param>
        /// <param name="alias">The property alias.</param>
        /// <param name="value">The deploy property value.</param>
        /// <remarks>
        /// This will loop through all the values stored inside the Vorto property, using the IValueConnector to parse each value.
        /// Due to how the ValueConnectors set the value, we have to create mocked content items and assign the value to it.
        /// Then the mock item is passed to the ValueConnector, matching the property type being wrapped by Vorto and the
        /// ValueConnector will parse the value.
        /// When the ValueConnector has done its work, the parsed value is extracted from the mock content and then assigned back
        /// to the original field inside the Vorto value object instead.
        /// </remarks>
        public void SetValue(IContentBase content, string alias, string value)
        {
            // if there's an empty value we don't need to do more work
            if (string.IsNullOrWhiteSpace(value))
            {
                content.SetValue(alias, value);
                return;
            }

            // fail fast if this isn't JSON
            if (value.DetectIsJson() == false)
            {
                return;
            }

            // try parsing this as a Vorto value
            var vortoValue = JsonConvert.DeserializeObject <VortoValue>(value);

            if (vortoValue == null)
            {
                return;
            }

            // old versions of Vorto doesn't seem to store a DtdGuid - in those cases we just deploy the value as it is without any further handling.
            if (string.IsNullOrWhiteSpace(vortoValue.DtdGuid))
            {
                LogHelper.Debug <VortoValueConnector>($"No datatype definition defined inside the Vorto property: {alias} - are you using an old version of Vorto? - data value will be deployed as it is.");
                content.SetValue(alias, value);
                return;
            }

            // getting the wrapped datatype via the Vorto datatype
            var vortoDataType             = _dataTypeService.GetDataTypeDefinitionById(Guid.Parse(vortoValue.DtdGuid));
            var vortoDataTypePrevalueJson = _dataTypeService.GetPreValuesCollectionByDataTypeId(vortoDataType.Id).FormatAsDictionary().FirstOrDefault(x => x.Key == "dataType").Value.Value;
            var vortoDataTypePrevalue     = JsonConvert.DeserializeObject <VortoDatatypePrevalue>(vortoDataTypePrevalueJson);

            var wrappedDataType = _dataTypeService.GetDataTypeDefinitionById(vortoDataTypePrevalue.Guid);

            // ensure the wrapped datatype is found
            if (wrappedDataType == null)
            {
                throw new InvalidOperationException($"Could not resolve the datatype used inside the Vorto property: {alias}");
            }

            var propertyType   = new PropertyType(wrappedDataType, MockPropertyTypeAlias);
            var valueConnector = ValueConnectors.Get(propertyType);

            // iterate values for each language
            foreach (var languageKey in vortoValue.Values.ValuePairs.Keys.ToArray())
            {
                var val = vortoValue.Values.ValuePairs[languageKey];

                var mockProperty = new Property(propertyType);
                var mockContent  = new Content("mockContent", -1, new ContentType(-1), new PropertyCollection(new List <Property> {
                    mockProperty
                }));

                // due to how ValueConnector.SetValue() works, we have to pass the mock item through the connector to have it do its
                // work on parsing the value on the item itself.
                valueConnector.SetValue(mockContent, mockProperty.Alias, val?.ToString());

                // get the value back and assign
                var convertedValue = mockContent.GetValue(mockProperty.Alias);
                vortoValue.Values.ValuePairs[languageKey] = convertedValue;
            }

            // Vorto does not use formatting when serializing JSON values
            value = JObject.FromObject(vortoValue).ToString(Formatting.None);
            content.SetValue(alias, value);
        }