diff --git a/.gitignore b/.gitignore
index 51405dd753..b6839b4e04 100644
--- a/.gitignore
+++ b/.gitignore
@@ -84,3 +84,4 @@ src/*.psess
NDependOut/*
*.ndproj
QueryResult.htm
+*.ndproj
diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
index 870ed2cc00..f290b5b54a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs
@@ -170,11 +170,31 @@ namespace Umbraco.Core.Persistence.Repositories
return content;
}
+ public override void DeleteVersion(Guid versionId)
+ {
+ var sql = new Sql()
+ .Select("*")
+ .From()
+ .InnerJoin().On(left => left.VersionId, right => right.VersionId)
+ .Where(x => x.VersionId == versionId)
+ .Where(x => x.Newest == true);
+ var dto = Database.Fetch(sql).FirstOrDefault();
+
+ if(dto == null) return;
+
+ using (var transaction = Database.GetTransaction())
+ {
+ PerformDeleteVersion(dto.NodeId, versionId);
+
+ transaction.Complete();
+ }
+ }
+
protected override void PerformDeleteVersion(int id, Guid versionId)
{
Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
- Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
- Database.Delete("WHERE nodeId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
+ Database.Delete("WHERE contentNodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
+ Database.Delete("WHERE ContentId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
}
@@ -340,19 +360,18 @@ namespace Umbraco.Core.Persistence.Repositories
}
}
+ //Look up (newest) entries by id in cmsDocument table to set newest = false
+ var documentDtos = Database.Fetch("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true });
+ foreach (var documentDto in documentDtos)
+ {
+ var docDto = documentDto;
+ docDto.Newest = false;
+ Database.Update(docDto);
+ }
+
var contentVersionDto = dto.ContentVersionDto;
if (shouldCreateNewVersion)
{
- //Look up (newest) entries by id in cmsDocument table to set newest = false
- //NOTE: This is only relevant when a new version is created, which is why its done inside this if-statement.
- var documentDtos = Database.Fetch("WHERE nodeId = @Id AND newest = @IsNewest", new { Id = entity.Id, IsNewest = true });
- foreach (var documentDto in documentDtos)
- {
- var docDto = documentDto;
- docDto.Newest = false;
- Database.Update(docDto);
- }
-
//Create a new version - cmsContentVersion
//Assumes a new Version guid and Version date (modified date) has been set
Database.Insert(contentVersionDto);
diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
index e27fac1ba3..8292fc8977 100644
--- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs
@@ -176,8 +176,8 @@ namespace Umbraco.Core.Persistence.Repositories
protected override void PerformDeleteVersion(int id, Guid versionId)
{
Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
- Database.Delete("WHERE nodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
- Database.Delete("WHERE nodeId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
+ Database.Delete("WHERE contentNodeId = @Id AND versionId = @VersionId", new { Id = id, VersionId = versionId });
+ Database.Delete("WHERE ContentId = @Id AND VersionId = @VersionId", new { Id = id, VersionId = versionId });
}
#endregion
diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
index 0ed84582fa..9b9160b66a 100644
--- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs
@@ -43,8 +43,8 @@ namespace Umbraco.Core.Persistence.Repositories
public virtual void DeleteVersion(Guid versionId)
{
- var dto = Database.FirstOrDefault("WHERE versionId = @VersionId AND newest = @Newest", new { VersionId = versionId, Newest = false });
- Mandate.That(dto != null);
+ var dto = Database.FirstOrDefault("WHERE versionId = @VersionId", new { VersionId = versionId });
+ if(dto == null) return;
using (var transaction = Database.GetTransaction())
{
@@ -56,8 +56,8 @@ namespace Umbraco.Core.Persistence.Repositories
public virtual void DeleteVersions(int id, DateTime versionDate)
{
- var list = Database.Fetch("WHERE nodeId = @Id AND VersionDate < @VersionDate", new { Id = id, VersionDate = versionDate });
- Mandate.That(list.Any());
+ var list = Database.Fetch("WHERE ContentId = @Id AND VersionDate < @VersionDate", new { Id = id, VersionDate = versionDate });
+ if (list.Any() == false) return;
using (var transaction = Database.GetTransaction())
{
diff --git a/src/Umbraco.Tests/Models/DataValueSetterTests.cs b/src/Umbraco.Tests/Models/DataValueSetterTests.cs
index db59217166..891c53dd0d 100644
--- a/src/Umbraco.Tests/Models/DataValueSetterTests.cs
+++ b/src/Umbraco.Tests/Models/DataValueSetterTests.cs
@@ -66,6 +66,7 @@ namespace Umbraco.Tests.Models
var dataTypeId = Guid.NewGuid();
var dataTypeData = MockRepository.GenerateMock();
+
dataTypeData
.Stub(data => data.ToXMl(Arg.Is.Anything))
.Return(null) // you have to call Return() even though we're about to override it
@@ -98,5 +99,18 @@ namespace Umbraco.Tests.Models
((IDataValueSetter)dataTypeData).AssertWasCalled(setter => setter.SetValue("Hello world", DataTypeDatabaseType.Nvarchar.ToString()));
}
+ [TestCase(DataTypeDatabaseType.Nvarchar)]
+ [TestCase(DataTypeDatabaseType.Date)]
+ [TestCase(DataTypeDatabaseType.Integer)]
+ [TestCase(DataTypeDatabaseType.Ntext)]
+ public void DefaultData_SetValue_Ensures_Empty_String_When_Null_Value_Any_Data_Type(DataTypeDatabaseType type)
+ {
+ var defaultData = new DefaultData(MockRepository.GenerateMock());
+
+ ((IDataValueSetter)defaultData).SetValue(null, type.ToString());
+
+ Assert.AreEqual(string.Empty, defaultData.Value);
+ }
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Tests/Services/ContentServiceTests.cs b/src/Umbraco.Tests/Services/ContentServiceTests.cs
index 522f608272..a8d3f6d30c 100644
--- a/src/Umbraco.Tests/Services/ContentServiceTests.cs
+++ b/src/Umbraco.Tests/Services/ContentServiceTests.cs
@@ -861,6 +861,22 @@ namespace Umbraco.Tests.Services
Assert.That(sut.GetValue("imgCropper"), Is.Empty);
}
+ [Test]
+ public void Can_Delete_Previous_Versions_Not_Latest()
+ {
+ // Arrange
+ var contentService = ServiceContext.ContentService;
+ var content = contentService.GetById(1049);
+ var version = content.Version;
+
+ // Act
+ contentService.DeleteVersion(1049, version, true, 0);
+ var sut = contentService.GetById(1049);
+
+ // Assert
+ Assert.That(sut.Version, Is.EqualTo(version));
+ }
+
private IEnumerable CreateContentHierarchy()
{
var contentType = ServiceContext.ContentTypeService.GetContentType("umbTextpage");
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
index c1c9f27a8a..9d9e65f151 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/create/PartialViewTasks.cs
@@ -101,8 +101,7 @@ namespace umbraco
{
//write out the template header
sw.Write("@inherits ");
- sw.Write(typeof(UmbracoViewPage<>).FullName.TrimEnd("`1"));
- sw.Write("");
+ sw.Write(typeof(UmbracoTemplatePage).FullName.TrimEnd("`1"));
}
public bool Delete()
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs
index ccd6c6481d..86446782fe 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/moveOrCopy.aspx.cs
@@ -272,11 +272,15 @@ namespace umbraco.dialogs
{
if (CurrentApp == Constants.Applications.Content)
{
- Services.ContentService.Move((IContent)currContent, Request.GetItemAs("copyTo"), getUser().Id);
+ //Backwards comp. change, so old events are fired #U4-2731
+ var doc = new Document(currContent as IContent);
+ doc.Move(Request.GetItemAs("copyTo"));
}
else
{
- Services.MediaService.Move((IMedia)currContent, Request.GetItemAs("copyTo"), getUser().Id);
+ //Backwards comp. change, so old events are fired #U4-2731
+ var media = new umbraco.cms.businesslogic.media.Media(currContent as IMedia);
+ media.Move(Request.GetItemAs("copyTo"));
library.ClearLibraryCacheForMedia(currContent.Id);
}
@@ -290,7 +294,9 @@ namespace umbraco.dialogs
{
//NOTE: We ONLY support Copy on content not media for some reason.
- var newContent = Services.ContentService.Copy((IContent)currContent, Request.GetItemAs("copyTo"), RelateDocuments.Checked, getUser().Id);
+ //Backwards comp. change, so old events are fired #U4-2731
+ var newContent = new Document(currContent as IContent);
+ newContent.Copy(Request.GetItemAs("copyTo"), getUser(), RelateDocuments.Checked);
feedback.Text = ui.Text("moveOrCopy", "copyDone", nodes, getUser()) + "
" + ui.Text("closeThisWindow") + "";
feedback.type = uicontrols.Feedback.feedbacktype.success;
diff --git a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs
index a974fda7c2..471fcc9479 100644
--- a/src/umbraco.cms/businesslogic/datatype/DefaultData.cs
+++ b/src/umbraco.cms/businesslogic/datatype/DefaultData.cs
@@ -65,6 +65,17 @@ namespace umbraco.cms.businesslogic.datatype
///
void IDataValueSetter.SetValue(object val, string strDbType)
{
+ //We need to ensure that val is not a null value, if it is then we'll convert this to an empty string.
+ //The reason for this is because by default the DefaultData.Value property returns an empty string when
+ // there is no value, this is based on the PropertyDataDto.GetValue return value which defaults to an
+ // empty string (which is called from this class's method LoadValueFromDatabase).
+ //Some legacy implementations of DefaultData are expecting an empty string when there is
+ // no value so we need to keep this consistent.
+ if (val == null)
+ {
+ val = string.Empty;
+ }
+
_value = val;
//now that we've set our value, we can update our BaseDataType object with the correct values from the db
//instead of making it query for itself. This is a peformance optimization enhancement.