diff --git a/src/Umbraco.Core/Models/IMacroProperty.cs b/src/Umbraco.Core/Models/IMacroProperty.cs
index c39e777a0e..a6c1d9ca5f 100644
--- a/src/Umbraco.Core/Models/IMacroProperty.cs
+++ b/src/Umbraco.Core/Models/IMacroProperty.cs
@@ -6,7 +6,7 @@ namespace Umbraco.Core.Models
///
/// Defines a Property for a Macro
///
- public interface IMacroProperty : IValueObject, IDeepCloneable
+ public interface IMacroProperty : IValueObject, IDeepCloneable, IRememberBeingDirty
{
[DataMember]
int Id { get; set; }
diff --git a/src/Umbraco.Core/Models/MacroPropertyCollection.cs b/src/Umbraco.Core/Models/MacroPropertyCollection.cs
index 7496b582b4..de23d60e7c 100644
--- a/src/Umbraco.Core/Models/MacroPropertyCollection.cs
+++ b/src/Umbraco.Core/Models/MacroPropertyCollection.cs
@@ -24,6 +24,44 @@ namespace Umbraco.Core.Models
}
return clone;
}
+
+ ///
+ /// Used to update an existing macro property
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// The existing property alias
+ ///
+ ///
+ public void UpdateProperty(string currentAlias, string name = null, int? sortOrder = null, string editorAlias = null, string newAlias = null)
+ {
+ var prop = this[currentAlias];
+ if (prop == null)
+ {
+ throw new InvalidOperationException("No property exists with alias " + currentAlias);
+ }
+
+ if (name.IsNullOrWhiteSpace() == false)
+ {
+ prop.Name = name;
+ }
+ if (sortOrder.HasValue)
+ {
+ prop.SortOrder = sortOrder.Value;
+ }
+ if (name.IsNullOrWhiteSpace() == false)
+ {
+ prop.EditorAlias = editorAlias;
+ }
+
+ if (newAlias.IsNullOrWhiteSpace() == false && currentAlias != newAlias)
+ {
+ prop.Alias = newAlias;
+ ChangeKey(currentAlias, newAlias);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/ObservableDictionary.cs b/src/Umbraco.Core/ObservableDictionary.cs
index b665071386..7e988e2b05 100644
--- a/src/Umbraco.Core/ObservableDictionary.cs
+++ b/src/Umbraco.Core/ObservableDictionary.cs
@@ -135,6 +135,28 @@ namespace Umbraco.Core
}
+ ///
+ /// Allows us to change the key of an item
+ ///
+ ///
+ ///
+ public virtual void ChangeKey(TKey currentKey, TKey newKey)
+ {
+ if (!Indecies.ContainsKey(currentKey))
+ {
+ throw new InvalidOperationException("No item with the key " + currentKey + "was found in the collection");
+ }
+ if (ContainsKey(newKey))
+ {
+ throw new DuplicateKeyException(newKey.ToString());
+ }
+
+ var currentIndex = Indecies[currentKey];
+
+ Indecies.Remove(currentKey);
+ Indecies.Add(newKey, currentIndex);
+ }
+
internal class DuplicateKeyException : Exception
{
diff --git a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
index 4fa6215477..c8ffcbe68a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MacroRepository.cs
@@ -165,9 +165,9 @@ namespace Umbraco.Core.Persistence.Repositories
Database.Update(dto);
- //update the sections if they've changed
+ //update the properties if they've changed
var macro = (Macro)entity;
- if (macro.IsPropertyDirty("Properties"))
+ if (macro.IsPropertyDirty("Properties") || macro.Properties.Any(x => x.IsDirty()))
{
//now we need to delete any props that have been removed
foreach (var propAlias in macro.RemovedProperties)
@@ -188,7 +188,11 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
- Database.Update(propDto);
+ //only update if it's dirty
+ if (macro.Properties[propDto.Alias].IsDirty())
+ {
+ Database.Update(propDto);
+ }
}
}
diff --git a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs
index 5907b6c6be..377b9e57e7 100644
--- a/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs
+++ b/src/Umbraco.Tests/Persistence/Repositories/MacroRepositoryTest.cs
@@ -364,7 +364,58 @@ namespace Umbraco.Tests.Persistence.Repositories
}
}
+ [Test]
+ public void Can_Update_Property_For_Macro()
+ {
+ // Arrange
+ var provider = new PetaPocoUnitOfWorkProvider();
+ var unitOfWork = provider.GetUnitOfWork();
+ using (var repository = new MacroRepository(unitOfWork, NullCacheProvider.Current))
+ {
+ var macro = repository.Get(1);
+ macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test"));
+ repository.AddOrUpdate(macro);
+ unitOfWork.Commit();
+ //Act
+ macro = repository.Get(1);
+ macro.Properties["new1"].Name = "this is a new name";
+ repository.AddOrUpdate(macro);
+ unitOfWork.Commit();
+
+
+ // Assert
+ var result = repository.Get(1);
+ Assert.AreEqual("new1", result.Properties.First().Alias);
+ Assert.AreEqual("this is a new name", result.Properties.First().Name);
+
+ }
+ }
+
+ [Test]
+ public void Can_Update_Macro_Property_Alias()
+ {
+ // Arrange
+ var provider = new PetaPocoUnitOfWorkProvider();
+ var unitOfWork = provider.GetUnitOfWork();
+ using (var repository = new MacroRepository(unitOfWork, NullCacheProvider.Current))
+ {
+ var macro = repository.Get(1);
+ macro.Properties.Add(new MacroProperty("new1", "New1", 3, "test"));
+ repository.AddOrUpdate(macro);
+ unitOfWork.Commit();
+
+ //Act
+ macro = repository.Get(1);
+ macro.Properties.UpdateProperty("new1", newAlias: "newAlias");
+ repository.AddOrUpdate(macro);
+ unitOfWork.Commit();
+
+ // Assert
+ var result = repository.Get(1);
+ Assert.AreEqual("newAlias", result.Properties.First().Alias);
+ }
+ }
[TearDown]
public override void TearDown()
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
index a50c2970de..50fb8b912e 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/developer/Macros/editMacro.aspx.cs
@@ -322,8 +322,6 @@ namespace umbraco.cms.presentation.developer
void Save_Click(object sender, EventArgs e)
{
- //disable the add validators
- macroProperties.
Page.Validate();
@@ -351,10 +349,14 @@ namespace umbraco.cms.presentation.developer
var macroElementType = (DropDownList)item.FindControl("macroPropertyType");
var prop = _macro.Properties.Single(x => x.Id == int.Parse(macroPropertyId.Value));
- prop.Alias = macroElementAlias.Text.Trim();
- prop.Name = macroElementName.Text.Trim();
- prop.EditorAlias = macroElementType.SelectedValue;
- prop.SortOrder = sort;
+
+ _macro.Properties.UpdateProperty(
+ prop.Alias,
+ macroElementName.Text.Trim(),
+ sort,
+ macroElementType.SelectedValue,
+ macroElementAlias.Text.Trim());
+
sort++;
}