diff --git a/src/Umbraco.Core/Models/PreValue.cs b/src/Umbraco.Core/Models/PreValue.cs
index 3d5f13f5ee..05b7a5f5df 100644
--- a/src/Umbraco.Core/Models/PreValue.cs
+++ b/src/Umbraco.Core/Models/PreValue.cs
@@ -9,7 +9,11 @@
{
Value = value;
Id = id;
+ }
+ public PreValue(string value)
+ {
+ Value = value;
}
///
diff --git a/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs b/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs
index 3f25171063..4639b1d068 100644
--- a/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs
+++ b/src/Umbraco.Core/PropertyEditors/PreValueEditor.cs
@@ -112,10 +112,10 @@ namespace Umbraco.Core.PropertyEditors
/// This can be overridden if perhaps you have a comma delimited string posted value but want to convert those to individual rows, or to convert
/// a json structure to multiple rows.
///
- public virtual IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
+ public virtual IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
{
//convert to a string based value to be saved in the db
- return editorValue.ToDictionary(x => x.Key, x => x.Value == null ? null : x.Value.ToString());
+ return editorValue.ToDictionary(x => x.Key, x => new PreValue(x.Value == null ? null : x.Value.ToString()));
}
///
diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs
index 230d01cbde..0ea5250ea8 100644
--- a/src/Umbraco.Core/Services/DataTypeService.cs
+++ b/src/Umbraco.Core/Services/DataTypeService.cs
@@ -217,6 +217,7 @@ namespace Umbraco.Core.Services
///
/// Id of the DataTypeDefinition to save PreValues for
/// List of string values to save
+ [Obsolete("This should no longer be used, use the alternative SavePreValues or SaveDataTypeAndPreValues methods instead. This will only insert pre-values without keys")]
public void SavePreValues(int id, IEnumerable values)
{
//TODO: Should we raise an event here since we are really saving values for the data type?
@@ -255,9 +256,10 @@ namespace Umbraco.Core.Services
///
///
///
- /// We will actually just remove all pre-values and re-insert them in one transaction
+ /// We need to actually look up each pre-value and maintain it's id if possible - this is because of silly property editors
+ /// like 'dropdown list publishing keys'
///
- internal void SavePreValues(int id, IDictionary values)
+ public void SavePreValues(int id, IDictionary values)
{
//TODO: Should we raise an event here since we are really saving values for the data type?
@@ -267,22 +269,7 @@ namespace Umbraco.Core.Services
{
using (var transaction = uow.Database.GetTransaction())
{
- uow.Database.Execute("DELETE FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = id });
-
- var sortOrder = 1;
- foreach (var value in values)
- {
- var dto = new DataTypePreValueDto
- {
- DataTypeNodeId = id,
- Value = value.Value,
- SortOrder = sortOrder,
- Alias = value.Key
- };
- uow.Database.Insert(dto);
- sortOrder++;
- }
-
+ AddOrUpdatePreValues(id, values, uow);
transaction.Complete();
}
}
@@ -295,7 +282,7 @@ namespace Umbraco.Core.Services
///
///
///
- public void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, IDictionary values, int userId = 0)
+ public void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, IDictionary values, int userId = 0)
{
if (Saving.IsRaisedEventCancelled(new SaveEventArgs(dataTypeDefinition), this))
return;
@@ -309,25 +296,7 @@ namespace Umbraco.Core.Services
repository.AddOrUpdate(dataTypeDefinition);
//complete the transaction, but run the delegate before the db transaction is finalized
- uow.Commit(database =>
- {
- //Execute this before the transaction is completed!
- database.Execute("DELETE FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId", new { DataTypeId = dataTypeDefinition.Id });
-
- var sortOrder = 1;
- foreach (var value in values)
- {
- var dto = new DataTypePreValueDto
- {
- DataTypeNodeId = dataTypeDefinition.Id,
- Value = value.Value,
- SortOrder = sortOrder,
- Alias = value.Key
- };
- database.Insert(dto);
- sortOrder++;
- }
- });
+ uow.Commit(database => AddOrUpdatePreValues(dataTypeDefinition.Id, values, uow));
Saved.RaiseEvent(new SaveEventArgs(dataTypeDefinition, false), this);
}
@@ -336,6 +305,56 @@ namespace Umbraco.Core.Services
Audit.Add(AuditTypes.Save, string.Format("Save DataTypeDefinition performed by user"), userId, dataTypeDefinition.Id);
}
+ private void AddOrUpdatePreValues(int id, IDictionary preValueCollection, IDatabaseUnitOfWork uow)
+ {
+ //first just get all pre-values for this data type so we can compare them to see if we need to insert or update or replace
+ var sql = new Sql().Select("*")
+ .From()
+ .Where(dto => dto.DataTypeNodeId == id)
+ .OrderBy(dto => dto.SortOrder);
+ var currentVals = uow.Database.Fetch(sql).ToArray();
+
+ //already existing, need to be updated
+ var valueIds = preValueCollection.Where(x => x.Value.Id > 0).Select(x => x.Value.Id).ToArray();
+ var existingByIds = currentVals.Where(x => valueIds.Contains(x.Id)).ToArray();
+
+ //These ones need to be removed from the db, they no longer exist in the new values
+ var deleteById = currentVals.Where(x => valueIds.Contains(x.Id) == false);
+
+ foreach (var d in deleteById)
+ {
+ uow.Database.Execute(
+ "DELETE FROM cmsDataTypePreValues WHERE datatypeNodeId = @DataTypeId AND id=@Id",
+ new { DataTypeId = id, Id = d.Id });
+ }
+
+ var sortOrder = 1;
+
+ foreach (var pre in preValueCollection)
+ {
+ var existing = existingByIds.FirstOrDefault(valueDto => valueDto.Id == pre.Value.Id);
+ if (existing != null)
+ {
+ existing.Value = pre.Value.Value;
+ existing.SortOrder = sortOrder;
+ uow.Database.Update(existing);
+ }
+ else
+ {
+ var dto = new DataTypePreValueDto
+ {
+ DataTypeNodeId = id,
+ Value = pre.Value.Value,
+ SortOrder = sortOrder,
+ Alias = pre.Key
+ };
+ uow.Database.Insert(dto);
+ }
+
+ sortOrder++;
+ }
+ }
+
///
/// Deletes an
///
diff --git a/src/Umbraco.Core/Services/IDataTypeService.cs b/src/Umbraco.Core/Services/IDataTypeService.cs
index 9b6f23bce3..e57d9016e4 100644
--- a/src/Umbraco.Core/Services/IDataTypeService.cs
+++ b/src/Umbraco.Core/Services/IDataTypeService.cs
@@ -10,8 +10,6 @@ namespace Umbraco.Core.Services
///
public interface IDataTypeService : IService
{
- void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, IDictionary values, int userId = 0);
-
///
/// Gets a by its Id
///
@@ -107,8 +105,24 @@ namespace Umbraco.Core.Services
///
/// Id of the DataTypeDefinition to save PreValues for
/// List of string values to save
+ [Obsolete("This should no longer be used, use the alternative SavePreValues or SaveDataTypeAndPreValues methods instead. This will only insert pre-values without keys")]
void SavePreValues(int id, IEnumerable values);
+ ///
+ /// Saves a list of PreValues for a given DataTypeDefinition
+ ///
+ /// Id of the DataTypeDefinition to save PreValues for
+ /// List of key/value pairs to save
+ void SavePreValues(int id, IDictionary values);
+
+ ///
+ /// Saves the data type and it's prevalues
+ ///
+ ///
+ ///
+ ///
+ void SaveDataTypeAndPreValues(IDataTypeDefinition dataTypeDefinition, IDictionary values, int userId = 0);
+
///
/// Gets a specific PreValue by its Id
///
diff --git a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.controller.js b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.controller.js
index bdddef9af4..c8d3c3c4a5 100644
--- a/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.controller.js
+++ b/src/Umbraco.Web.UI.Client/src/views/prevalueeditors/multivalues.controller.js
@@ -10,7 +10,10 @@ angular.module("umbraco").controller("Umbraco.Editors.MultiValuesController",
//make an array from the dictionary
var items = [];
for (var i in $scope.model.value) {
- items.push({value: $scope.model.value[i]});
+ items.push({
+ value: $scope.model.value[i],
+ id: i
+ });
}
//now make the editor model the array
$scope.model.value = items;
diff --git a/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs
index 64a88af37f..1e8a7ba088 100644
--- a/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/PreValueFieldDisplay.cs
@@ -8,11 +8,6 @@ namespace Umbraco.Web.Models.ContentEditing
[DataContract(Name = "preValue", Namespace = "")]
public class PreValueFieldDisplay : PreValueFieldSave
{
- /////
- ///// The id of the pre-value field
- /////
- //[DataMember(Name = "id", IsRequired = true)]
- //public int Id { get; set; }
///
/// The name to display for this pre-value field
diff --git a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
index 8f230cd9c5..4e90c9c6c0 100644
--- a/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/FileUploadPropertyEditor.cs
@@ -164,7 +164,7 @@ namespace Umbraco.Web.PropertyEditors
///
///
///
- public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
+ public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
{
var result = base.ConvertEditorToDb(editorValue, currentValue);
@@ -173,7 +173,7 @@ namespace Umbraco.Web.PropertyEditors
var values = result.Select(item => item.Value).ToList();
result.Clear();
- result.Add("thumbs", string.Join(";", values));
+ result.Add("thumbs", new PreValue(string.Join(";", values)));
return result;
}
}
diff --git a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
index 879b232d3c..8b476adba0 100644
--- a/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/MultipleTextStringPropertyEditor.cs
@@ -56,7 +56,7 @@ namespace Umbraco.Web.PropertyEditors
///
///
///
- public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
+ public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
{
//the values from the editor will be min/max fieds and we need to format to json in one field
var min = (editorValue.ContainsKey("min") ? editorValue["min"].ToString() : "0").TryConvertTo();
@@ -64,7 +64,7 @@ namespace Umbraco.Web.PropertyEditors
var json = JObject.FromObject(new {Minimum = min.Success ? min.Result : 0, Maximum = max.Success ? max.Result : 0});
- return new Dictionary {{"0", json.ToString(Formatting.None)}};
+ return new Dictionary { { "0", new PreValue(json.ToString(Formatting.None)) } };
}
///
diff --git a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs
index 717dd4e53f..437e7d4a1b 100644
--- a/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs
+++ b/src/Umbraco.Web/PropertyEditors/ValueListPreValueEditor.cs
@@ -78,10 +78,10 @@ namespace Umbraco.Web.PropertyEditors
///
/// This is mostly because we want to maintain compatibility with v6 drop down property editors that store their prevalues in different db rows.
///
- public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
+ public override IDictionary ConvertEditorToDb(IDictionary editorValue, PreValueCollection currentValue)
{
var val = editorValue["items"] as JArray;
- var result = new Dictionary();
+ var result = new Dictionary();
if (val == null)
{
@@ -93,12 +93,18 @@ namespace Umbraco.Web.PropertyEditors
var index = 0;
//get all values in the array that are not empty
- foreach (var asString in val.OfType()
+ foreach (var item in val.OfType()
.Where(jItem => jItem["value"] != null)
- .Select(jItem => jItem["value"].ToString())
- .Where(asString => asString.IsNullOrWhiteSpace() == false))
+ .Select(jItem => new
+ {
+ idAsString = jItem["id"] == null ? "0" : jItem["id"].ToString(),
+ valAsString = jItem["value"].ToString()
+ })
+ .Where(x => x.valAsString.IsNullOrWhiteSpace() == false))
{
- result.Add(index.ToInvariantString(), asString);
+ var id = 0;
+ int.TryParse(item.idAsString, out id);
+ result.Add(index.ToInvariantString(), new PreValue(id, item.valAsString));
index++;
}
}