diff --git a/LinqToUmbraco/src/umbraco.Linq/Core/umbraco.Linq.Core.csproj b/LinqToUmbraco/src/umbraco.Linq/Core/umbraco.Linq.Core.csproj index 8da30d905a..f269238f7c 100644 --- a/LinqToUmbraco/src/umbraco.Linq/Core/umbraco.Linq.Core.csproj +++ b/LinqToUmbraco/src/umbraco.Linq/Core/umbraco.Linq.Core.csproj @@ -22,7 +22,7 @@ true full false - ..\..\..\..\umbraco\presentation\bin\ + bin\Debug\ DEBUG;TRACE prompt 4 @@ -31,22 +31,11 @@ pdbonly true - ..\..\..\..\umbraco\presentation\bin\ + bin\Release\ TRACE prompt 4 - ..\..\..\..\umbraco\presentation\bin\umbraco.Linq.Core.XML - - - true - ..\..\..\..\umbraco\presentation\bin\ - DEBUG;TRACE - ..\..\..\..\umbraco\presentation\bin\Umbraco.Linq.Core.XML - full - AnyCPU - true - GlobalSuppressions.cs - prompt + bin\Release\umbraco.Linq.Core.XML diff --git a/components/editorControls/umbraco.editorControls.csproj b/components/editorControls/umbraco.editorControls.csproj index 3474e75d7c..3d0431cd7f 100644 --- a/components/editorControls/umbraco.editorControls.csproj +++ b/components/editorControls/umbraco.editorControls.csproj @@ -49,7 +49,7 @@ v3.5 - ..\..\umbraco\presentation\bin\ + bin\Debug\ false 285212672 false @@ -72,14 +72,14 @@ prompt - ..\..\umbraco\presentation\bin\ + bin\Release\ false 285212672 false TRACE - ..\..\umbraco\presentation\bin\umbraco.editorControls.XML + bin\Release\umbraco.editorControls.XML false 4096 false diff --git a/components/macroRenderings/umbraco.macroRenderings.csproj b/components/macroRenderings/umbraco.macroRenderings.csproj index 5000b9e60b..724adb7e04 100644 --- a/components/macroRenderings/umbraco.macroRenderings.csproj +++ b/components/macroRenderings/umbraco.macroRenderings.csproj @@ -34,7 +34,7 @@ v3.5 - ..\..\umbraco\presentation\bin\ + bin\Debug\ false 285212672 false @@ -57,14 +57,14 @@ prompt - ..\..\umbraco\presentation\bin\ + bin\Release\ false 285212672 false TRACE - ..\..\umbraco\presentation\bin\umbraco.macroRenderings.XML + bin\Release\umbraco.macroRenderings.XML false 4096 false diff --git a/components/umbraco.controls/umbraco.controls.csproj b/components/umbraco.controls/umbraco.controls.csproj index 089c452066..4b8d46b8bc 100644 --- a/components/umbraco.controls/umbraco.controls.csproj +++ b/components/umbraco.controls/umbraco.controls.csproj @@ -24,7 +24,7 @@ true full false - ..\..\umbraco\presentation\bin\ + bin\Debug\ DEBUG;TRACE prompt 4 @@ -34,11 +34,11 @@ pdbonly true - ..\..\umbraco\presentation\bin\ + bin\Release\ TRACE prompt 4 - ..\..\umbraco\presentation\bin\controls.XML + bin\Release\controls.XML diff --git a/components/umbraco.webservices/umbraco.webservices.csproj b/components/umbraco.webservices/umbraco.webservices.csproj index 5fcc28472a..19062a2ede 100644 --- a/components/umbraco.webservices/umbraco.webservices.csproj +++ b/components/umbraco.webservices/umbraco.webservices.csproj @@ -21,7 +21,7 @@ true full false - ..\..\umbraco\presentation\bin\ + bin\Debug\ DEBUG;TRACE prompt 4 @@ -29,11 +29,11 @@ pdbonly true - ..\..\umbraco\presentation\bin\ + bin\Release\ TRACE prompt 4 - ..\..\umbraco\presentation\bin\umbraco.webservices.XML + bin\Release\umbraco.webservices.XML diff --git a/foreign dlls/ClientDependency.Core.dll b/foreign dlls/ClientDependency.Core.dll index 1d3ccb6dfe..410ebe6006 100644 Binary files a/foreign dlls/ClientDependency.Core.dll and b/foreign dlls/ClientDependency.Core.dll differ diff --git a/umbraco.Test/DocumentTest.cs b/umbraco.Test/DocumentTest.cs index 29a6ea7143..acb1224dae 100644 --- a/umbraco.Test/DocumentTest.cs +++ b/umbraco.Test/DocumentTest.cs @@ -34,8 +34,6 @@ namespace umbraco.Test public class DocumentTest { - #region Unit Tests - /// /// Creates a bunch of nodes in a heirarchy, then deletes the top most node (moves to the recycle bin /// and completely deletes from system.) This should completely delete all of these nodes from the database. @@ -460,7 +458,6 @@ namespace umbraco.Test Assert.AreEqual(0, RecycleBin.Count(RecycleBin.RecycleBinType.Content)); } - #endregion #region TEST TO BE WRITTEN diff --git a/umbraco.Test/DocumentTypeTest.cs b/umbraco.Test/DocumentTypeTest.cs index 2ee7f4d9a4..e88b6610df 100644 --- a/umbraco.Test/DocumentTypeTest.cs +++ b/umbraco.Test/DocumentTypeTest.cs @@ -8,6 +8,7 @@ using System.Linq; using umbraco.cms.businesslogic.template; using umbraco.cms.businesslogic.datatype; using System.Data.SqlClient; +using umbraco.cms.businesslogic; namespace umbraco.Test { @@ -23,7 +24,7 @@ namespace umbraco.Test public class DocumentTypeTest { [TestMethod()] - public void DocumentType_DeleteDocTypeWithContennt() + public void DocumentType_DeleteDocTypeWithContent() { var dt = CreateNewDocType(); var doc = Document.MakeNew("TEST" + Guid.NewGuid().ToString("N"), dt, m_User, -1); diff --git a/umbraco.Test/MediaTest.cs b/umbraco.Test/MediaTest.cs new file mode 100644 index 0000000000..45c629889d --- /dev/null +++ b/umbraco.Test/MediaTest.cs @@ -0,0 +1,468 @@ +using umbraco.cms.businesslogic.media; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using System; +using System.Collections.Generic; +using umbraco.BusinessLogic; +using System.Linq; +using umbraco.editorControls.textfield; +using umbraco.editorControls.label; +using umbraco.cms.businesslogic.datatype; +using umbraco.cms.businesslogic; + +namespace umbraco.Test +{ + + + /// + ///This is a test class for MediaTest and is intended + ///to contain all MediaTest Unit Tests + /// + [TestClass()] + public class MediaTest + { + /// + ///A test for making a new media and deleting it which actuall first moves it to the recycle bin + ///and then deletes it. + /// + [TestMethod()] + public void Media_MakeNewTest() + { + //System.Diagnostics.Debugger.Break(); + Assert.IsInstanceOfType(m_NewRootMedia, typeof(Media)); + } + + [TestMethod()] + public void Media_DeleteHeirarchyPermanentlyTest() + { + var mediaList = new List(); + var total = 20; + var mt = new MediaType(GetExistingMediaTypeId()); + //allow the doc type to be created underneath itself + mt.AllowedChildContentTypeIDs = new int[] { mt.Id }; + mt.Save(); + + //create 20 content nodes underneath each other, this will test deleting with heirarchy as well + var lastParentId = -1; + for (var i = 0; i < total; i++) + { + var newDoc = Media.MakeNew(i.ToString() + Guid.NewGuid().ToString("N"), mt, m_User, lastParentId); + mediaList.Add(newDoc); + Assert.IsTrue(mediaList[mediaList.Count - 1].Id > 0); + lastParentId = newDoc.Id; + } + + //now delete all of them permanently, since they are nested, we only need to delete one + mediaList.First().delete(true); + + //make sure they are all gone + foreach (var d in mediaList) + { + Assert.IsFalse(Media.IsNode(d.Id)); + } + + } + + [TestMethod] + public void Media_MoveTest() + { + //first need to document type that allows other types of document types to exist underneath it + MediaType parent = null; + MediaType child = null; + var ids = MediaType.getAllUniqueNodeIdsFromObjectType(MediaType._objectType); + foreach (var id in ids) + { + var dt = new MediaType(id); + var allowed = dt.AllowedChildContentTypeIDs.ToList(); + if (allowed.Count() > 0) + { + parent = dt; + child = new MediaType(allowed[0]); + break; + } + } + if (parent == null || child == null) + { + throw new NotImplementedException("The umbraco install doesn't have document types that support a heirarchy"); + } + + //now that we have a parent and a child, we need to create some documents + var node1 = Media.MakeNew("FromCopy" + Guid.NewGuid().ToString("N"), parent, m_User, -1); + Assert.IsTrue(node1.Id > 0); + + var node2 = Media.MakeNew("ToCopy" + Guid.NewGuid().ToString("N"), parent, m_User, -1); + Assert.IsTrue(node2.Id > 0); + + //we now have 2 nodes in the root of the same type, we'll create a child node under node1 and move it to node2 + var childNode = Media.MakeNew("ChildCopy" + Guid.NewGuid().ToString("N"), child, m_User, node2.Id); + Assert.IsTrue(childNode.Id > 0); + + childNode.Move(node2.Id); + Assert.AreEqual(node2.Id, childNode.Parent.Id); + + RecycleAndDelete(childNode); + RecycleAndDelete(node2); + RecycleAndDelete(node1); + } + + [TestMethod()] + public void Media_DeleteAllDocsByDocumentTypeTest() + { + //System.Diagnostics.Debugger.Break(); + + //create a new media type + string name = "TEST-" + Guid.NewGuid().ToString("N"); + var mt = MediaType.MakeNew(m_User, name); + + //test the media type + Assert.AreEqual(DateTime.Now.Date, mt.CreateDateTime.Date); + Assert.IsTrue(mt.Id > 0); + + //allow itself to be created under itself + mt.AllowedChildContentTypeIDs = new int[] { mt.Id }; + //create a tab + mt.AddVirtualTab("TEST"); + + //test the tab + var tabs = mt.getVirtualTabs.ToList(); + Assert.AreEqual(1, tabs.Count); + + //create a property + var allDataTypes = DataTypeDefinition.GetAll().ToList(); //get all definitions + mt.AddPropertyType(allDataTypes[0], "testProperty", "Test Property"); //add a property type of the first type found in the list + + //test the prop + var prop = mt.getPropertyType("testProperty"); + Assert.AreEqual("Test Property", prop.Name); + + //create 1st node + var node1 = Media.MakeNew("TEST-" + Guid.NewGuid().ToString("N"), mt, m_User, -1); + Assert.IsTrue(node1.Id > 0); + + //create 2nd node underneath node 1 + var node2 = Media.MakeNew("TEST-" + Guid.NewGuid().ToString("N"), mt, m_User, node1.Id); + Assert.IsTrue(node2.Id > 0); + Assert.AreEqual(node1.Id, node2.Parent.Id); + + //create 3rd node underneath node 2 + var node3 = Media.MakeNew("TEST-" + Guid.NewGuid().ToString("N"), mt, m_User, node2.Id); + Assert.IsTrue(node3.Id > 0); + Assert.AreEqual(node2.Id, node3.Parent.Id); + + Media.DeleteFromType(mt); + + Assert.IsFalse(Media.IsNode(node1.Id)); + Assert.IsFalse(Media.IsNode(node2.Id)); + Assert.IsFalse(Media.IsNode(node3.Id)); + + //now remove the document type created + mt.delete(); + + Assert.IsFalse(MediaType.IsNode(mt.Id)); + } + + [TestMethod] + public void Media_EmptyRecycleBinTest() + { + //System.Diagnostics.Debugger.Break(); + + var mediaList = new List(); + var total = 20; + var mt = m_ExistingMediaType; + //allow the doc type to be created underneath itself + mt.AllowedChildContentTypeIDs = new int[] { mt.Id }; + mt.Save(); + + //create 20 media nodes underneath each other, this will test deleting with heirarchy as well + var lastParentId = -1; + for (var i = 0; i < total; i++) + { + var newMedia = Media.MakeNew("R-" + i.ToString() + Guid.NewGuid().ToString("N"), mt, m_User, lastParentId); + mediaList.Add(newMedia); + Assert.IsTrue(mediaList[mediaList.Count - 1].Id > 0); + Assert.AreEqual(lastParentId, newMedia.ParentId); + lastParentId = newMedia.Id; + } + + //now delete all of them, since they are nested, we only need to delete one + mediaList.First().delete(); + + //a callback action for each item removed from the recycle bin + var totalDeleted = 0; + + var bin = new RecycleBin(RecycleBin.RecycleBinType.Media); + var totalTrashedItems = bin.GetDescendants().Cast().Count(); + bin.CallTheGarbageMan(x => + { + Assert.AreEqual(totalTrashedItems - (++totalDeleted), x); + }); + + Assert.AreEqual(0, RecycleBin.Count(RecycleBin.RecycleBinType.Media)); + } + + [TestMethod] + public void Media_UndeleteTest() + { + //find existing content + var media = new Media(GetExistingNodeId()); + //create new content based on the existing content in the same heirarchy + var mt = new MediaType(media.ContentType.Id); + var parentId = media.ParentId; + var newMedia = Media.MakeNew("NewMedia" + Guid.NewGuid().ToString("N"), mt, m_User, parentId); + Assert.IsTrue(newMedia.Id > 0); + + //this will recycle the node + newMedia.delete(); + Assert.IsTrue(newMedia.IsTrashed); + Assert.IsTrue(newMedia.Path.Contains("," + (int)RecycleBin.RecycleBinType.Media + ",")); + + //undelete the node (move it) + newMedia.Move(parentId); + Assert.IsFalse(newMedia.IsTrashed); + Assert.IsFalse(newMedia.Path.Contains("," + (int)RecycleBin.RecycleBinType.Media + ",")); + + //remove it completely + RecycleAndDelete(newMedia); + } + + #region Tests to write + + ///// + /////A test for Children + ///// + //[TestMethod()] + //public void ChildrenTest() + //{ + // Guid id = new Guid(); // TODO: Initialize to an appropriate value + // Media target = new Media(id); // TODO: Initialize to an appropriate value + // Media[] actual; + // actual = target.Children; + // Assert.Inconclusive("Verify the correctness of this test method."); + //} + + ///// + /////A test for Save + ///// + //[TestMethod()] + //public void SaveTest() + //{ + // Guid id = new Guid(); // TODO: Initialize to an appropriate value + // Media target = new Media(id); // TODO: Initialize to an appropriate value + // target.Save(); + // Assert.Inconclusive("A method that does not return a value cannot be verified."); + //} + + ///// + /////A test for GetRootMedias + ///// + //[TestMethod()] + //public void GetRootMediasTest() + //{ + // Media[] expected = null; // TODO: Initialize to an appropriate value + // Media[] actual; + // actual = Media.GetRootMedias(); + // Assert.AreEqual(expected, actual); + // Assert.Inconclusive("Verify the correctness of this test method."); + //} + + ///// + /////A test for GetChildrenForTree + ///// + //[TestMethod()] + //public void GetChildrenForTreeTest() + //{ + // int nodeId = 0; // TODO: Initialize to an appropriate value + // List expected = null; // TODO: Initialize to an appropriate value + // List actual; + // actual = Media.GetChildrenForTree(nodeId); + // Assert.AreEqual(expected, actual); + // Assert.Inconclusive("Verify the correctness of this test method."); + //} + + ///// + /////A test for DeleteFromType + ///// + //[TestMethod()] + //public void DeleteFromTypeTest() + //{ + // MediaType dt = null; // TODO: Initialize to an appropriate value + // Media.DeleteFromType(dt); + // Assert.Inconclusive("A method that does not return a value cannot be verified."); + //} + + ///// + /////A test for delete + ///// + //[TestMethod()] + //public void deleteTest() + //{ + // Guid id = new Guid(); // TODO: Initialize to an appropriate value + // Media target = new Media(id); // TODO: Initialize to an appropriate value + // target.delete(); + // Assert.Inconclusive("A method that does not return a value cannot be verified."); + //} + #endregion + + #region Private properties and methods + + /// + /// The user to be used to create stuff + /// + private User m_User = new User(0); + + /// + /// Used for each test initialization. Before each test is run a new root media is created. + /// + private Media m_NewRootMedia; + + /// + /// Gets initialized for each test and is set to an existing document type + /// + private MediaType m_ExistingMediaType; + + private void RecycleAndDelete(Media m) + { + if (m == null) + { + return; + } + + var id = m.Id; + + //check if it is already trashed + var alreadyTrashed = m.IsTrashed; + + if (!alreadyTrashed) + { + //now recycle it + m.delete(); + + Assert.IsTrue(m.IsTrashed); + } + + //now permanently delete + m.delete(true); + Assert.IsFalse(Media.IsNode(id)); + + //check with sql that it is gone + var count = Application.SqlHelper.ExecuteScalar("SELECT COUNT(*) FROM umbracoNode WHERE id=@id", + Application.SqlHelper.CreateParameter("@id", id)); + + Assert.AreEqual(0, count); + } + + private int GetExistingNodeId() + { + var ids = Media.getAllUniqueNodeIdsFromObjectType(Media._objectType).ToList(); + var r = new Random(); + var index = r.Next(0, ids.Count() - 1); + return ids[index]; + } + + private Media CreateNewUnderRoot(MediaType mt) + { + string Name = "TEST-" + Guid.NewGuid().ToString("N"); + int ParentId = -1; + Media actual = Media.MakeNew(Name, mt, m_User, ParentId); + var id = actual.Id; + Assert.IsTrue(actual.Id > 0); + return actual; + } + + private MediaType GetExistingDocType() + { + MediaType dct = new MediaType(GetExistingMediaTypeId()); + Assert.IsTrue(dct.Id > 0); + return dct; + } + + private MediaType GetExistingMediaType() + { + MediaType dct = new MediaType(GetExistingMediaTypeId()); + Assert.IsTrue(dct.Id > 0); + return dct; + } + + private int GetExistingMediaTypeId() + { + var types = MediaType.GetAll.ToList(); + MediaType found = null; + DataTypeNoEdit lblField = new DataTypeNoEdit(); + foreach (var d in types) + { + var prop = d.PropertyTypes + .Where(x => x.DataTypeDefinition.DataType.Id == lblField.Id).FirstOrDefault(); + if (prop != null) + { + found = d; + break; + } + } + if (found == null) + { + throw new MissingMemberException("No media type was found that contains a label property"); + } + return found.Id; + } + + #endregion + + #region Test Context + private TestContext testContextInstance; + + /// + ///Gets or sets the test context which provides + ///information about and functionality for the current test run. + /// + public TestContext TestContext + { + get + { + return testContextInstance; + } + set + { + testContextInstance = value; + } + } + #endregion + + #region Initialize and cleanup + // + //You can use the following additional attributes as you write your tests: + // + //Use ClassInitialize to run code before running the first test in the class + //[ClassInitialize()] + //public static void MyClassInitialize(TestContext testContext) + //{ + //} + // + //Use ClassCleanup to run code after all tests in a class have run + //[ClassCleanup()] + //public static void MyClassCleanup() + //{ + //} + // + + /// + /// Creates a new root document to use for each test if required + /// + [TestInitialize()] + public void MyTestInitialize() + { + m_ExistingMediaType = GetExistingMediaType(); + m_NewRootMedia = CreateNewUnderRoot(m_ExistingMediaType); + } + + /// + /// Makes sure the root doc is deleted + /// + [TestCleanup()] + public void MyTestCleanup() + { + RecycleAndDelete(m_NewRootMedia); + } + #endregion + + + } +} diff --git a/umbraco.Test/umbraco.Test.csproj b/umbraco.Test/umbraco.Test.csproj index 8a59fd8f3f..085b4b42fc 100644 --- a/umbraco.Test/umbraco.Test.csproj +++ b/umbraco.Test/umbraco.Test.csproj @@ -116,6 +116,7 @@ + diff --git a/umbraco.sln b/umbraco.sln index 874fbc6ec7..055c00fe85 100644 --- a/umbraco.sln +++ b/umbraco.sln @@ -152,82 +152,56 @@ Global CategoryFile = umbraco.vsmdi EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug - Fixed Version|Any CPU = Debug - Fixed Version|Any CPU Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {651E1350-91B6-44B7-BD60-7207006D7003}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {651E1350-91B6-44B7-BD60-7207006D7003}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {651E1350-91B6-44B7-BD60-7207006D7003}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {651E1350-91B6-44B7-BD60-7207006D7003}.Debug|Any CPU.Build.0 = Debug|Any CPU {651E1350-91B6-44B7-BD60-7207006D7003}.Release|Any CPU.ActiveCfg = Release|Any CPU {651E1350-91B6-44B7-BD60-7207006D7003}.Release|Any CPU.Build.0 = Release|Any CPU - {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Release|Any CPU.ActiveCfg = Release|Any CPU {E469A9CE-1BEC-423F-AC44-713CD72457EA}.Release|Any CPU.Build.0 = Release|Any CPU - {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Debug|Any CPU.Build.0 = Debug|Any CPU {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Release|Any CPU.ActiveCfg = Release|Any CPU {CCD75EC3-63DB-4184-B49D-51C1DD337230}.Release|Any CPU.Build.0 = Release|Any CPU - {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Debug|Any CPU.Build.0 = Debug|Any CPU {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Release|Any CPU.ActiveCfg = Release|Any CPU {511F6D8D-7717-440A-9A57-A507E9A8B27F}.Release|Any CPU.Build.0 = Release|Any CPU - {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Debug|Any CPU.Build.0 = Debug|Any CPU {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Release|Any CPU.ActiveCfg = Release|Any CPU {255F5DF1-4E43-4758-AC05-7A0B68EB021B}.Release|Any CPU.Build.0 = Release|Any CPU - {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Debug|Any CPU.Build.0 = Debug|Any CPU {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Release|Any CPU.ActiveCfg = Release|Any CPU {52AB8F1F-FB76-4E8C-885F-0747B6CE71EC}.Release|Any CPU.Build.0 = Release|Any CPU - {D7636876-0756-43CB-A192-138C6F0D5E42}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {D7636876-0756-43CB-A192-138C6F0D5E42}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {D7636876-0756-43CB-A192-138C6F0D5E42}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D7636876-0756-43CB-A192-138C6F0D5E42}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7636876-0756-43CB-A192-138C6F0D5E42}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7636876-0756-43CB-A192-138C6F0D5E42}.Release|Any CPU.Build.0 = Release|Any CPU - {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU {C7CB79F0-1C97-4B33-BFA7-00731B579AE2}.Release|Any CPU.Build.0 = Release|Any CPU - {6EDD2061-82F2-461B-BB6E-879245A832DE}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {6EDD2061-82F2-461B-BB6E-879245A832DE}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {6EDD2061-82F2-461B-BB6E-879245A832DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6EDD2061-82F2-461B-BB6E-879245A832DE}.Debug|Any CPU.Build.0 = Debug|Any CPU {6EDD2061-82F2-461B-BB6E-879245A832DE}.Release|Any CPU.ActiveCfg = Release|Any CPU {6EDD2061-82F2-461B-BB6E-879245A832DE}.Release|Any CPU.Build.0 = Release|Any CPU - {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Debug|Any CPU.Build.0 = Debug|Any CPU {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {CBDB56AC-FF02-4421-9FD4-ED82E339D8E2}.Release|Any CPU.Build.0 = Release|Any CPU - {31CAEC36-0C3D-4D69-B092-84866811EA07}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug - Fixed Version|Any CPU - {31CAEC36-0C3D-4D69-B092-84866811EA07}.Debug - Fixed Version|Any CPU.Build.0 = Debug - Fixed Version|Any CPU {31CAEC36-0C3D-4D69-B092-84866811EA07}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {31CAEC36-0C3D-4D69-B092-84866811EA07}.Debug|Any CPU.Build.0 = Debug|Any CPU {31CAEC36-0C3D-4D69-B092-84866811EA07}.Release|Any CPU.ActiveCfg = Release|Any CPU {31CAEC36-0C3D-4D69-B092-84866811EA07}.Release|Any CPU.Build.0 = Release|Any CPU - {27A2590E-1313-4A33-89FD-92811540B69C}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU {27A2590E-1313-4A33-89FD-92811540B69C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {27A2590E-1313-4A33-89FD-92811540B69C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6277C9FB-3A9A-4537-AA86-82DA9B2527FD}.Debug - Fixed Version|Any CPU.ActiveCfg = Debug|Any CPU - {6277C9FB-3A9A-4537-AA86-82DA9B2527FD}.Debug - Fixed Version|Any CPU.Build.0 = Debug|Any CPU {6277C9FB-3A9A-4537-AA86-82DA9B2527FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6277C9FB-3A9A-4537-AA86-82DA9B2527FD}.Debug|Any CPU.Build.0 = Debug|Any CPU {6277C9FB-3A9A-4537-AA86-82DA9B2527FD}.Release|Any CPU.ActiveCfg = Release|Any CPU diff --git a/umbraco/businesslogic/GlobalSettings.cs b/umbraco/businesslogic/GlobalSettings.cs index f5d29cdc6e..91ffab839e 100644 --- a/umbraco/businesslogic/GlobalSettings.cs +++ b/umbraco/businesslogic/GlobalSettings.cs @@ -105,7 +105,7 @@ namespace umbraco { get { - + try { return ConfigurationManager.AppSettings["umbracoPath"]; @@ -117,19 +117,19 @@ namespace umbraco } } - /// - /// Gets the path to umbraco's client directory (/umbraco_client by default). - /// This is a relative path to the Umbraco Path as it always must exist beside the 'umbraco' - /// folder since the CSS paths to images depend on it. - /// - /// The path. - public static string ClientPath - { - get - { - return Path + "/../umbraco_client"; - } - } + /// + /// Gets the path to umbraco's client directory (/umbraco_client by default). + /// This is a relative path to the Umbraco Path as it always must exist beside the 'umbraco' + /// folder since the CSS paths to images depend on it. + /// + /// The path. + public static string ClientPath + { + get + { + return Path + "/../umbraco_client"; + } + } /// /// Gets the database connection string @@ -150,7 +150,7 @@ namespace umbraco } set { - if(DbDSN!=value) + if (DbDSN != value) SaveSetting("umbracoDbDSN", value); } } @@ -178,32 +178,39 @@ namespace umbraco } } - private static AspNetHostingPermissionLevel m_ApplicationTrustLevel; - public static AspNetHostingPermissionLevel ApplicationTrustLevel { - get{ - if (m_ApplicationTrustLevel != AspNetHostingPermissionLevel.None) { + private static AspNetHostingPermissionLevel? m_ApplicationTrustLevel = null; + public static AspNetHostingPermissionLevel ApplicationTrustLevel + { + get + { + if (!m_ApplicationTrustLevel.HasValue) + { + //set minimum + m_ApplicationTrustLevel = AspNetHostingPermissionLevel.None; - foreach (AspNetHostingPermissionLevel trustLevel in - new AspNetHostingPermissionLevel[] { - AspNetHostingPermissionLevel.Unrestricted, - AspNetHostingPermissionLevel.High, - AspNetHostingPermissionLevel.Medium, - AspNetHostingPermissionLevel.Low, - AspNetHostingPermissionLevel.Minimal - }) { - try { - new AspNetHostingPermission(trustLevel).Demand(); - } catch (System.Security.SecurityException) { - continue; + //determine maximum + foreach (AspNetHostingPermissionLevel trustLevel in + new AspNetHostingPermissionLevel[] { + AspNetHostingPermissionLevel.Unrestricted, + AspNetHostingPermissionLevel.High, + AspNetHostingPermissionLevel.Medium, + AspNetHostingPermissionLevel.Low, + AspNetHostingPermissionLevel.Minimal + }) + { + try + { + new AspNetHostingPermission(trustLevel).Demand(); + m_ApplicationTrustLevel = trustLevel; + break; //we've set the highest permission we can + } + catch (System.Security.SecurityException) + { + continue; + } } - - m_ApplicationTrustLevel = trustLevel; } - - m_ApplicationTrustLevel = AspNetHostingPermissionLevel.None; - } - - return m_ApplicationTrustLevel; + return m_ApplicationTrustLevel.Value; } } @@ -212,14 +219,19 @@ namespace umbraco /// Forces umbraco to be medium trust compatible /// /// If true, umbraco will be medium-trust compatible, no matter what Permission level the server is on. - public static bool UseMediumTrust { - get { - try { + public static bool UseMediumTrust + { + get + { + try + { if (ApplicationTrustLevel == AspNetHostingPermissionLevel.High || ApplicationTrustLevel == AspNetHostingPermissionLevel.Unrestricted) return false; - else + else return bool.Parse(ConfigurationManager.AppSettings["umbracoUseMediumTrust"]); - }catch { + } + catch + { return false; } } @@ -233,8 +245,10 @@ namespace umbraco protected static void SaveSetting(string key, string value) { WebConfigurationFileMap webConfig = new WebConfigurationFileMap(); - foreach (VirtualDirectoryMapping v in webConfig.VirtualDirectories) { - if (v.IsAppRoot) { + foreach (VirtualDirectoryMapping v in webConfig.VirtualDirectories) + { + if (v.IsAppRoot) + { Configuration config = WebConfigurationManager.OpenWebConfiguration(v.VirtualDirectory); config.AppSettings.Settings[key].Value = value; config.Save(); @@ -250,7 +264,7 @@ namespace umbraco /* Configuration config = ConfigurationManager.OpenMappedExeConfiguration(webConfig, ConfigurationUserLevel.None); */ - + } /// @@ -309,12 +323,12 @@ namespace umbraco string configStatus = ConfigurationStatus; string currentVersion = CurrentVersion; - + if (currentVersion != configStatus) Log.Add(LogTypes.Debug, User.GetUser(0), -1, "CurrentVersion different from configStatus: '" + currentVersion + "','" + configStatus + "'"); - + return (configStatus == currentVersion); } catch @@ -420,7 +434,7 @@ namespace umbraco try { System.Net.Configuration.MailSettingsSectionGroup mailSettings = ConfigurationManager.GetSection("system.net/mailSettings") as System.Net.Configuration.MailSettingsSectionGroup; - + if (mailSettings != null) return mailSettings.Smtp.Network.Host; else @@ -525,8 +539,10 @@ namespace umbraco /// Gets a value indicating whether statistic logging happens async. /// /// true if async stats logging is enabled; otherwise, false. - public static bool EnableAsyncStatLogging { - get { + public static bool EnableAsyncStatLogging + { + get + { string value = ConfigurationManager.AppSettings["umbracoAsyncStatLogging"]; bool result; if (!string.IsNullOrEmpty(value) && bool.TryParse(value, out result)) @@ -611,7 +627,7 @@ namespace umbraco /// public static bool RequestIsInUmbracoApplication(HttpContext context) { - return context.Request.Path.ToLower().IndexOf( IOHelper.ResolveUrl( SystemDirectories.Umbraco ) .ToLower()) > -1; + return context.Request.Path.ToLower().IndexOf(IOHelper.ResolveUrl(SystemDirectories.Umbraco).ToLower()) > -1; } public static bool RequestIsLiveEditRedirector(HttpContext context) @@ -623,7 +639,7 @@ namespace umbraco /// Gets a value indicating whether umbraco should force a secure (https) connection to the backoffice. /// /// true if [use SSL]; otherwise, false. - public static bool UseSSL + public static bool UseSSL { get { @@ -715,8 +731,8 @@ namespace umbraco } return false; } - } - + } + /// /// Determines whether the specified URL is reserved or is inside a reserved path. @@ -772,7 +788,7 @@ namespace umbraco } } - + /// /// Structure that checks in logarithmic time @@ -845,7 +861,7 @@ namespace umbraco // let the default string comparer deal with null or when part is not smaller then whole if (part == null || whole == null || part.Length >= whole.Length) return _stringComparer.Compare(part, whole); - + // loop through all characters that part and whole have in common int pos = 0; bool match; diff --git a/umbraco/businesslogic/Utils/TypeResolver.cs b/umbraco/businesslogic/Utils/TypeResolver.cs index 971cfc1e9f..7b1dcedeb4 100644 --- a/umbraco/businesslogic/Utils/TypeResolver.cs +++ b/umbraco/businesslogic/Utils/TypeResolver.cs @@ -58,23 +58,25 @@ namespace umbraco.BusinessLogic.Utils sandbox = AppDomain.CreateDomain("Sandbox", AppDomain.CurrentDomain.Evidence, domainSetup); } - try - { - TypeResolver typeResolver = (TypeResolver)sandbox.CreateInstanceAndUnwrap( - typeof(TypeResolver).Assembly.GetName().Name, - typeof(TypeResolver).FullName); + try + { + TypeResolver typeResolver = (TypeResolver)sandbox.CreateInstanceAndUnwrap( + typeof(TypeResolver).Assembly.GetName().Name, + typeof(TypeResolver).FullName); - return typeResolver.GetTypes(typeof(T), files); - } - catch(Exception ex) - { - Debug.WriteLine(ex.ToString()); - } - - if ((!GlobalSettings.UseMediumTrust) && (GlobalSettings.ApplicationTrustLevel > AspNetHostingPermissionLevel.Medium)) { - AppDomain.Unload(sandbox); + return typeResolver.GetTypes(typeof(T), files); + } + catch (Exception ex) + { + Debug.WriteLine(ex.ToString()); + } + finally + { + if ((!GlobalSettings.UseMediumTrust) && (GlobalSettings.ApplicationTrustLevel > AspNetHostingPermissionLevel.Medium)) + { + AppDomain.Unload(sandbox); + } } - return new string[0]; } diff --git a/umbraco/cms/businesslogic/Content.cs b/umbraco/cms/businesslogic/Content.cs index 3c8a85bf56..c0c27ee228 100644 --- a/umbraco/cms/businesslogic/Content.cs +++ b/umbraco/cms/businesslogic/Content.cs @@ -370,7 +370,6 @@ namespace umbraco.cms.businesslogic if (Deep) { - //store children array here because iterating over an Array object is very inneficient. var childs = this.Children; foreach (BusinessLogic.console.IconI c in childs) { diff --git a/umbraco/cms/businesslogic/RecycleBin.cs b/umbraco/cms/businesslogic/RecycleBin.cs index e12f296164..40c818174e 100644 --- a/umbraco/cms/businesslogic/RecycleBin.cs +++ b/umbraco/cms/businesslogic/RecycleBin.cs @@ -150,7 +150,7 @@ namespace umbraco.cms.businesslogic itemDeletedCallback(RecycleBin.Count(m_BinType)); break; case RecycleBinType.Media: - new Media(c.Id).delete(); + new Media(c.Id).delete(true); itemDeletedCallback(RecycleBin.Count(m_BinType)); break; } diff --git a/umbraco/cms/businesslogic/media/Media.cs b/umbraco/cms/businesslogic/media/Media.cs index a1a2e1f03d..9367abd7e1 100644 --- a/umbraco/cms/businesslogic/media/Media.cs +++ b/umbraco/cms/businesslogic/media/Media.cs @@ -6,6 +6,7 @@ using System.Collections; using System.Collections.Generic; using umbraco.IO; using System.Xml; +using System.Linq; namespace umbraco.cms.businesslogic.media { @@ -16,7 +17,8 @@ namespace umbraco.cms.businesslogic.media /// public class Media : Content { - private const string m_SQLOptimizedChildren = @" + #region Constants and static members + private const string m_SQLOptimizedMany = @" select count(children.id) as children, umbracoNode.id, umbracoNode.uniqueId, umbracoNode.level, umbracoNode.parentId, umbracoNode.path, umbracoNode.sortOrder, umbracoNode.createDate, umbracoNode.nodeUser, umbracoNode.text, cmsContentType.icon, cmsContentType.alias, cmsContentType.thumbnail, cmsContentType.description, cmsContentType.masterContentType, cmsContentType.nodeId as contentTypeId @@ -27,23 +29,163 @@ namespace umbraco.cms.businesslogic.media where {0} group by umbracoNode.id, umbracoNode.uniqueId, umbracoNode.level, umbracoNode.parentId, umbracoNode.path, umbracoNode.sortOrder, umbracoNode.createDate, umbracoNode.nodeUser, umbracoNode.text, cmsContentType.icon, cmsContentType.alias, cmsContentType.thumbnail, cmsContentType.description, cmsContentType.masterContentType, cmsContentType.nodeId - order by {1}"; + order by {1}"; + #endregion - /// - /// Contructs a media object given the Id - /// - /// Identifier + #region Constructors + /// + /// Contructs a media object given the Id + /// + /// Identifier public Media(int id) : base(id) { } - /// - /// Contructs a media object given the Id - /// - /// Identifier + /// + /// Contructs a media object given the Id + /// + /// Identifier public Media(Guid id) : base(id) { } public Media(int id, bool noSetup) : base(id, noSetup) { } - public Media(bool optimizedMode, int id) : base(id, optimizedMode) { } + public Media(bool optimizedMode, int id) : base(id, optimizedMode) { } + #endregion + + #region Static Methods + /// + /// - + /// + public static Guid _objectType = new Guid("b796f64c-1f99-4ffb-b886-4bf4bc011a9c"); + + /// + /// Creates a new Media + /// + /// The name of the media + /// The type of the media + /// The user creating the media + /// The id of the folder under which the media is created + /// + public static Media MakeNew(string Name, MediaType dct, BusinessLogic.User u, int ParentId) + { + Guid newId = Guid.NewGuid(); + // Updated to match level from base node + CMSNode n = new CMSNode(ParentId); + int newLevel = n.Level; + newLevel++; + CMSNode.MakeNew(ParentId, _objectType, u.Id, newLevel, Name, newId); + Media tmp = new Media(newId); + tmp.CreateContent(dct); + + NewEventArgs e = new NewEventArgs(); + tmp.OnNew(e); + + return tmp; + } + + /// + /// Retrieve a list of all toplevel medias and folders + /// + /// + public static Media[] GetRootMedias() + { + Guid[] topNodeIds = CMSNode.TopMostNodeIds(_objectType); + + Media[] retval = new Media[topNodeIds.Length]; + for (int i = 0; i < topNodeIds.Length; i++) + { + Media d = new Media(topNodeIds[i]); + retval[i] = d; + } + return retval; + } + + public static List GetChildrenForTree(int nodeId) + { + + List tmp = new List(); + using (IRecordsReader dr = + SqlHelper.ExecuteReader( + string.Format(m_SQLOptimizedMany + , "umbracoNode.parentID = @parentId And umbracoNode.nodeObjectType = @type" + , "umbracoNode.sortOrder") + , SqlHelper.CreateParameter("@type", _objectType) + , SqlHelper.CreateParameter("@parentId", nodeId))) + { + + while (dr.Read()) + { + Media d = new Media(dr.GetInt("id"), true); + d.PopulateMediaFromReader(dr); + tmp.Add(d); + } + + } + return tmp; + } + + public static IEnumerable GetMediaOfMediaType(int mediaTypeId) + { + var tmp = new List(); + using (IRecordsReader dr = + SqlHelper.ExecuteReader( + string.Format(m_SQLOptimizedMany, "cmsContent.contentType = @contentTypeId", "umbracoNode.sortOrder"), + SqlHelper.CreateParameter("@contentTypeId", mediaTypeId))) + { + while (dr.Read()) + { + Media d = new Media(dr.GetInt("id"), true); + d.PopulateMediaFromReader(dr); + tmp.Add(d); + } + } + + return tmp.ToArray(); + } + + /// + /// Deletes all medias of the given type, used when deleting a mediatype + /// + /// Use with care. + /// + /// + public static void DeleteFromType(MediaType dt) + { + //get all document for the document type and order by level (top level first) + var medias = Media.GetMediaOfMediaType(dt.Id) + .OrderByDescending(x => x.Level); + + foreach (Media media in medias) + { + //before we delete this document, we need to make sure we don't end up deleting other documents that + //are not of this document type that are children. So we'll move all of it's children to the trash first. + foreach (Media m in media.GetDescendants()) + { + if (m.ContentType.Id != dt.Id) + { + m.MoveToTrash(); + } + } + + media.DeletePermanently(); + } + } + + #endregion + + #region Public Properties + /// + /// Retrieve a list of all medias underneath the current + /// + public new Media[] Children + { + get + { + //return refactored optimized method + return Media.GetChildrenForTree(this.Id).ToArray(); + } + } + #endregion + + #region Public methods /// /// Used to persist object changes to the database. In Version3.0 it's just a stub for future compatibility @@ -53,7 +195,8 @@ namespace umbraco.cms.businesslogic.media SaveEventArgs e = new SaveEventArgs(); FireBeforeSave(e); - if (!e.Cancel) { + if (!e.Cancel) + { base.Save(); @@ -71,227 +214,178 @@ namespace umbraco.cms.businesslogic.media } } - - /// - /// - - /// - public static Guid _objectType = new Guid("b796f64c-1f99-4ffb-b886-4bf4bc011a9c"); - - /// - /// Creates a new Media - /// - /// The name of the media - /// The type of the media - /// The user creating the media - /// The id of the folder under which the media is created - /// - public static Media MakeNew(string Name, MediaType dct, BusinessLogic.User u, int ParentId) - { - Guid newId = Guid.NewGuid(); - // Updated to match level from base node - CMSNode n = new CMSNode(ParentId); - int newLevel = n.Level; - newLevel++; - CMSNode.MakeNew(ParentId,_objectType, u.Id, newLevel, Name, newId); - Media tmp = new Media(newId); - tmp.CreateContent(dct); - - NewEventArgs e = new NewEventArgs(); - tmp.OnNew(e); - - return tmp; - } - - /// - /// Retrieve a list of all toplevel medias and folders - /// - /// - public static Media[] GetRootMedias() - { - Guid[] topNodeIds = CMSNode.TopMostNodeIds(_objectType); - - Media[] retval = new Media[topNodeIds.Length]; - for (int i = 0;i < topNodeIds.Length;i++) - { - Media d = new Media(topNodeIds[i]); - retval[i] = d; - } - return retval; - } - - - /// - /// Retrieve a list of all medias underneath the current - /// - new public Media[] Children - { - get - { - //return refactored optimized method - return Media.GetChildrenForTree(this.Id).ToArray(); - } - } - - public static List GetChildrenForTree(int nodeId) - { - - List tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedChildren - , "umbracoNode.parentID = @parentId And umbracoNode.nodeObjectType = @type" - , "umbracoNode.sortOrder") - , SqlHelper.CreateParameter("@type", _objectType) - , SqlHelper.CreateParameter("@parentId", nodeId))) - { - - while (dr.Read()) - { - Media d = new Media(dr.GetInt("id"), true); - bool _hc = false; - if (dr.GetInt("children") > 0) - _hc = true; - int? masterContentType = null; - if (!dr.IsNull("masterContentType")) - masterContentType = dr.GetInt("masterContentType"); - d.SetupMediaForTree(dr.GetGuid("uniqueId") - , dr.GetShort("level") - , dr.GetInt("parentId") - , dr.GetInt("nodeUser") - , dr.GetString("path") - , dr.GetString("text") - , dr.GetDateTime("createDate") - , dr.GetString("icon") - , _hc - , dr.GetString("alias") - , dr.GetString("thumbnail") - , dr.GetString("description") - , masterContentType - , dr.GetInt("contentTypeId")); - tmp.Add(d); - } - - } - return tmp; - } - - private void SetupMediaForTree(Guid uniqueId, int level, int parentId, int user, string path, - string text, DateTime createDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, - string contentTypeDesc, int? masterContentType, int contentTypeId) - { - SetupNodeForTree(uniqueId, _objectType, level, parentId, user, path, text, createDate, hasChildren); - ContentType = new ContentType(contentTypeId, contentTypeAlias, icon, contentTypeThumb, masterContentType); - ContentTypeIcon = icon; - } - - /// - /// Deletes all medias of the given type, used when deleting a mediatype - /// - /// Use with care. - /// - /// - public static void DeleteFromType(MediaType dt) - { - var objs = Media.getContentOfContentType(dt); - foreach (Content c in objs) - { - // due to recursive structure document might already been deleted.. - if (CMSNode.IsNode(c.UniqueId)) - { - Media tmp = new Media(c.UniqueId); - tmp.delete(); - } - } - } - /// - /// Deletes the current media and all children. - /// - public override void delete() - { - // Check for recyle bin - if (!Path.Contains("," + ((int)RecycleBin.RecycleBinType.Media).ToString() + ",")) - { - MoveToTrashEventArgs e = new MoveToTrashEventArgs(); - FireBeforeMoveToTrash(e); + /// Moves the media to the trash + /// + public override void delete() + { + MoveToTrash(); + } - if (!e.Cancel) - { - Move((int)RecycleBin.RecycleBinType.Media); + /// + /// With either move the media to the trash or permanently remove it from the database. + /// + /// flag to set whether or not to completely remove it from the database or just send to trash + public void delete(bool deletePermanently) + { + if (!deletePermanently) + { + MoveToTrash(); + } + else + { + DeletePermanently(); + } + } - //TODO: Now that we've moved it to trash, we need to move the actual files so they are no longer accessible - //from the original URL. + public override IEnumerable GetDescendants() + { + var tmp = new List(); + using (IRecordsReader dr = SqlHelper.ExecuteReader( + string.Format(m_SQLOptimizedMany, "umbracoNode.path LIKE '%," + this.Id + ",%'", "umbracoNode.level"))) + { + while (dr.Read()) + { + Media d = new Media(dr.GetInt("id"), true); + d.PopulateMediaFromReader(dr); + tmp.Add(d); + } + } - FireAfterMoveToTrash(e); - } - } - else - { - DeleteEventArgs e = new DeleteEventArgs(); + return tmp.ToArray(); + } - FireBeforeDelete(e); + #endregion - if (!e.Cancel) - { - var children = this.Children; - foreach (Media d in children) - { - d.delete(); - } + #region Protected methods + protected void PopulateMediaFromReader(IRecordsReader dr) + { + bool _hc = false; + if (dr.GetInt("children") > 0) + _hc = true; + int? masterContentType = null; + if (!dr.IsNull("masterContentType")) + masterContentType = dr.GetInt("masterContentType"); + SetupMediaForTree(dr.GetGuid("uniqueId") + , dr.GetShort("level") + , dr.GetInt("parentId") + , dr.GetInt("nodeUser") + , dr.GetString("path") + , dr.GetString("text") + , dr.GetDateTime("createDate") + , dr.GetString("icon") + , _hc + , dr.GetString("alias") + , dr.GetString("thumbnail") + , dr.GetString("description") + , masterContentType + , dr.GetInt("contentTypeId")); + } + #endregion - // Remove all files - interfaces.IDataType uploadField = new cms.businesslogic.datatype.controls.Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")); - var props = this.getProperties; - foreach (cms.businesslogic.property.Property p in props) - { - FileInfo mediaFile = new FileInfo(IOHelper.MapPath(p.Value.ToString())); + #region Private methods + private void SetupMediaForTree(Guid uniqueId, int level, int parentId, int user, string path, + string text, DateTime createDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, + string contentTypeDesc, int? masterContentType, int contentTypeId) + { + SetupNodeForTree(uniqueId, _objectType, level, parentId, user, path, text, createDate, hasChildren); + ContentType = new ContentType(contentTypeId, contentTypeAlias, icon, contentTypeThumb, masterContentType); + ContentTypeIcon = icon; + } - if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id - && p.Value.ToString() != "" - && mediaFile.Exists) - { + /// + /// Used internally to permanently delete the data from the database + /// + /// returns true if deletion isn't cancelled + private bool DeletePermanently() + { + DeleteEventArgs e = new DeleteEventArgs(); - mediaFile.Delete(); + FireBeforeDelete(e); - string file = p.Value.ToString(); - string extension = ((string)file.Substring(file.LastIndexOf(".") + 1, file.Length - file.LastIndexOf(".") - 1)).ToLower(); + if (!e.Cancel) + { + foreach (Media m in Children.ToList()) + { + m.DeletePermanently(); + } - //check for thumbnail - if (",jpeg,jpg,gif,bmp,png,tiff,tif,".IndexOf("," + extension + ",") > -1) - { - string thumbnailfile = file.Replace("." + extension, "_thumb"); + // Remove all files + interfaces.IDataType uploadField = new cms.businesslogic.datatype.controls.Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")); + foreach (cms.businesslogic.property.Property p in this.getProperties.ToList()) + { + FileInfo mediaFile = new FileInfo(IOHelper.MapPath(p.Value.ToString())); - if (System.IO.File.Exists(IOHelper.MapPath(thumbnailfile + ".jpg"))) - System.IO.File.Delete(IOHelper.MapPath(thumbnailfile + ".jpg")); + if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id + && p.Value.ToString() != "" + && mediaFile.Exists) + { - //should also delete extra thumbnails - } + mediaFile.Delete(); - } + string file = p.Value.ToString(); + string extension = ((string)file.Substring(file.LastIndexOf(".") + 1, file.Length - file.LastIndexOf(".") - 1)).ToLower(); - } + //check for thumbnail + if (",jpeg,jpg,gif,bmp,png,tiff,tif,".IndexOf("," + extension + ",") > -1) + { + string thumbnailfile = file.Replace("." + extension, "_thumb"); - base.delete(); + if (System.IO.File.Exists(IOHelper.MapPath(thumbnailfile + ".jpg"))) + System.IO.File.Delete(IOHelper.MapPath(thumbnailfile + ".jpg")); - FireAfterDelete(e); - } - } + //should also delete extra thumbnails + } + + } + + } + + base.delete(); + + FireAfterDelete(e); + } + return !e.Cancel; + } + + /// + /// Used internally to move the node to the recyle bin + /// + /// Returns true if the move was not cancelled + private bool MoveToTrash() + { + MoveToTrashEventArgs e = new MoveToTrashEventArgs(); + FireBeforeMoveToTrash(e); + + if (!e.Cancel) + { + Move((int)RecycleBin.RecycleBinType.Media); + + //TODO: Now that we've moved it to trash, we need to move the actual files so they are no longer accessible + //from the original URL. + + FireAfterMoveToTrash(e); + } + return !e.Cancel; - } + } + + #endregion + + #region Events - //EVENTS /// /// The save event handler /// - public new delegate void SaveEventHandler(Media sender, SaveEventArgs e); + public delegate void SaveEventHandler(Media sender, SaveEventArgs e); /// /// The new event handler /// - public new delegate void NewEventHandler(Media sender, NewEventArgs e); + public delegate void NewEventHandler(Media sender, NewEventArgs e); /// /// The delete event handler /// - public new delegate void DeleteEventHandler(Media sender, DeleteEventArgs e); + public delegate void DeleteEventHandler(Media sender, DeleteEventArgs e); /// @@ -302,7 +396,8 @@ namespace umbraco.cms.businesslogic.media /// Raises the event. /// /// The instance containing the event data. - protected new virtual void FireBeforeSave(SaveEventArgs e) { + protected new virtual void FireBeforeSave(SaveEventArgs e) + { if (BeforeSave != null) BeforeSave(this, e); } @@ -315,7 +410,8 @@ namespace umbraco.cms.businesslogic.media /// Raises the event. /// /// The instance containing the event data. - protected new virtual void FireAfterSave(SaveEventArgs e) { + protected new virtual void FireAfterSave(SaveEventArgs e) + { if (AfterSave != null) AfterSave(this, e); } @@ -323,12 +419,13 @@ namespace umbraco.cms.businesslogic.media /// /// Occurs when [new]. /// - public new static event NewEventHandler New; + public static event NewEventHandler New; /// /// Raises the event. /// /// The instance containing the event data. - protected new virtual void OnNew(NewEventArgs e) { + protected virtual void OnNew(NewEventArgs e) + { if (New != null) New(this, e); } @@ -341,7 +438,8 @@ namespace umbraco.cms.businesslogic.media /// Raises the event. /// /// The instance containing the event data. - protected new virtual void FireBeforeDelete(DeleteEventArgs e) { + protected new virtual void FireBeforeDelete(DeleteEventArgs e) + { if (BeforeDelete != null) BeforeDelete(this, e); } @@ -354,42 +452,44 @@ namespace umbraco.cms.businesslogic.media /// Raises the event. /// /// The instance containing the event data. - protected new virtual void FireAfterDelete(DeleteEventArgs e) { + protected new virtual void FireAfterDelete(DeleteEventArgs e) + { if (AfterDelete != null) AfterDelete(this, e); } - /// - /// The Move to trash event handler - /// - public delegate void MoveToTrashEventHandler(Media sender, MoveToTrashEventArgs e); - /// - /// Occurs when [before delete]. - /// - public static event MoveToTrashEventHandler BeforeMoveToTrash; - /// - /// Raises the event. - /// - /// The instance containing the event data. - protected virtual void FireBeforeMoveToTrash(MoveToTrashEventArgs e) - { - if (BeforeMoveToTrash != null) - BeforeMoveToTrash(this, e); - } + /// + /// The Move to trash event handler + /// + public delegate void MoveToTrashEventHandler(Media sender, MoveToTrashEventArgs e); + /// + /// Occurs when [before delete]. + /// + public static event MoveToTrashEventHandler BeforeMoveToTrash; + /// + /// Raises the event. + /// + /// The instance containing the event data. + protected virtual void FireBeforeMoveToTrash(MoveToTrashEventArgs e) + { + if (BeforeMoveToTrash != null) + BeforeMoveToTrash(this, e); + } - /// - /// Occurs when [after move to trash]. - /// - public static event MoveToTrashEventHandler AfterMoveToTrash; - /// - /// Fires the after move to trash. - /// - /// The instance containing the event data. - protected virtual void FireAfterMoveToTrash(MoveToTrashEventArgs e) - { - if (AfterMoveToTrash != null) - AfterMoveToTrash(this, e); - } + /// + /// Occurs when [after move to trash]. + /// + public static event MoveToTrashEventHandler AfterMoveToTrash; + /// + /// Fires the after move to trash. + /// + /// The instance containing the event data. + protected virtual void FireAfterMoveToTrash(MoveToTrashEventArgs e) + { + if (AfterMoveToTrash != null) + AfterMoveToTrash(this, e); + } + #endregion } } diff --git a/umbraco/cms/businesslogic/media/MediaType.cs b/umbraco/cms/businesslogic/media/MediaType.cs index af0331d3f6..8ae62115d3 100644 --- a/umbraco/cms/businesslogic/media/MediaType.cs +++ b/umbraco/cms/businesslogic/media/MediaType.cs @@ -55,13 +55,10 @@ namespace umbraco.cms.businesslogic.media SqlHelper.CreateParameter("@alias",Alias))); } - - private static Guid _objectType = new Guid("4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e"); - /// /// Retrieve all MediaTypes in the umbraco installation /// - new public static MediaType[] GetAll + public new static MediaType[] GetAll { get { @@ -95,11 +92,12 @@ namespace umbraco.cms.businesslogic.media return mt; } + public static Guid _objectType = new Guid("4ea4382b-2f5a-4c2b-9587-ae9b3cf3602e"); /// /// Deletes the current MediaType and all created Medias of the type. /// - new public void delete() + public override void delete() { DeleteEventArgs e = new DeleteEventArgs(); FireBeforeDelete(e); diff --git a/umbraco/cms/businesslogic/web/Document.cs b/umbraco/cms/businesslogic/web/Document.cs index b7147ef96c..32f8acc682 100644 --- a/umbraco/cms/businesslogic/web/Document.cs +++ b/umbraco/cms/businesslogic/web/Document.cs @@ -219,49 +219,328 @@ namespace umbraco.cms.businesslogic.web //private Dictionary _knownProperties = new Dictionary(); //private Func, string, bool> propertyTypeByAlias = (pt, alias) => pt.Key.PropertyType.Alias == alias; - #endregion - + #endregion + + #region Static Methods + /// - /// Indexed property to return the property value by name + /// Imports (create) a document from a xmlrepresentation of a document, used by the packager /// - /// + /// The id to import to + /// Creator of the new document + /// Xmlsource + public static int Import(int ParentId, User Creator, XmlElement Source) + { + Document d = MakeNew( + Source.GetAttribute("nodeName"), + DocumentType.GetByAlias(Source.GetAttribute("nodeTypeAlias")), + Creator, + ParentId); + + d.CreateDateTime = DateTime.Parse(Source.GetAttribute("createDate")); + + // Properties + foreach (XmlElement n in Source.SelectNodes("data")) + { + Property prop = d.getProperty(n.GetAttribute("alias")); + string propValue = xmlHelper.GetNodeValue(n); + + // only update real values + if (!String.IsNullOrEmpty(propValue)) + { + //test if the property has prevalues, of so, try to convert the imported values so they match the new ones + SortedList prevals = cms.businesslogic.datatype.PreValues.GetPreValues(prop.PropertyType.DataTypeDefinition.Id); + + //Okey we found some prevalue, let's replace the vals with some ids + if (prevals.Count > 0) + { + System.Collections.Generic.List list = new System.Collections.Generic.List(propValue.Split(',')); + + foreach (DictionaryEntry item in prevals) + { + string pval = ((umbraco.cms.businesslogic.datatype.PreValue)item.Value).Value; + string pid = ((umbraco.cms.businesslogic.datatype.PreValue)item.Value).Id.ToString(); + + if (list.Contains(pval)) + list[list.IndexOf(pval)] = pid; + + } + + //join the list of new values and return it as the new property value + System.Text.StringBuilder builder = new System.Text.StringBuilder(); + bool isFirst = true; + + foreach (string str in list) + { + if (!isFirst) + builder.Append(","); + + builder.Append(str); + isFirst = false; + } + prop.Value = builder.ToString(); + + } + else + prop.Value = propValue; + } + } + + // Subpages + foreach (XmlElement n in Source.SelectNodes("node")) + Import(d.Id, Creator, n); + + return d.Id; + } + + /// + /// Creates a new document + /// + /// The name (.Text property) of the document + /// The documenttype + /// The usercontext under which the action are performed + /// The id of the parent to the document + /// The newly created document + public static Document MakeNew(string Name, DocumentType dct, User u, int ParentId) + { + //allows you to cancel a document before anything goes to the DB + var newingArgs = new DocumentNewingEventArgs() + { + Text = Name, + DocumentType = dct, + User = u, + ParentId = ParentId + }; + Document.OnNewing(newingArgs); + if (newingArgs.Cancel) + { + return null; + } + + + Guid newId = Guid.NewGuid(); + + // Updated to match level from base node + CMSNode n = new CMSNode(ParentId); + int newLevel = n.Level; + newLevel++; + MakeNew(ParentId, _objectType, u.Id, newLevel, Name, newId); + Document tmp = new Document(newId, true); + tmp.CreateContent(dct); + SqlHelper.ExecuteNonQuery("insert into cmsDocument (newest, nodeId, published, documentUser, versionId, Text) values (1, " + + tmp.Id + ", 0, " + + u.Id + ", @versionId, @text)", + SqlHelper.CreateParameter("@versionId", tmp.Version), + SqlHelper.CreateParameter("@text", tmp.Text)); + + // Update the sortOrder if the parent was the root! + if (ParentId == -1) + { + CMSNode c = new CMSNode(newId); + c.sortOrder = GetRootDocuments().Length + 1; + } + + Document d = new Document(newId); + + //event + NewEventArgs e = new NewEventArgs(); + d.OnNew(e); + + // Log + Log.Add(LogTypes.New, u, d.Id, ""); + + // Run Handler + umbraco.BusinessLogic.Actions.Action.RunActionHandlers(d, ActionNew.Instance); + + // Save doc + d.Save(); + + return d; + } + + /// + /// Used to get the firstlevel/root documents of the hierachy + /// + /// Root documents + public static Document[] GetRootDocuments() + { + Guid[] topNodeIds = TopMostNodeIds(_objectType); + + Document[] retval = new Document[topNodeIds.Length]; + for (int i = 0; i < topNodeIds.Length; i++) + { + Document d = new Document(topNodeIds[i]); + retval[i] = d; + } + return retval; + } + + public static int CountSubs(int parentId, bool publishedOnly) + { + if (!publishedOnly) + { + return CountSubs(parentId); + } + else + { + return SqlHelper.ExecuteScalar("SELECT COUNT(distinct nodeId) FROM umbracoNode INNER JOIN cmsDocument ON cmsDocument.published = 1 and cmsDocument.nodeId = umbracoNode.id WHERE ','+path+',' LIKE '%," + parentId.ToString() + ",%'"); + } + } + + /// + /// Deletes all documents of a type, will be invoked if a documenttype is deleted. + /// + /// Note: use with care: this method can result in wast amount of data being deleted. + /// + /// The type of which documents should be deleted + public static void DeleteFromType(DocumentType dt) + { + //get all document for the document type and order by level (top level first) + var docs = Document.GetDocumentsOfDocumentType(dt.Id) + .OrderByDescending(x => x.Level); + + foreach (Document doc in docs) + { + //before we delete this document, we need to make sure we don't end up deleting other documents that + //are not of this document type that are children. So we'll move all of it's children to the trash first. + foreach (Document c in doc.GetDescendants()) + { + if (c.ContentType.Id != dt.Id) + { + c.MoveToTrash(); + } + } + + doc.DeletePermanently(); + } + } + + public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) + { + var tmp = new List(); + using (IRecordsReader dr = + SqlHelper.ExecuteReader( + string.Format(m_SQLOptimizedMany, "cmsContent.contentType = @contentTypeId", "umbracoNode.sortOrder"), + SqlHelper.CreateParameter("@contentTypeId", docTypeId))) + { + while (dr.Read()) + { + Document d = new Document(dr.GetInt("id"), true); + d.PopulateDocumentFromReader(dr); + tmp.Add(d); + } + } + + return tmp.ToArray(); + } + + /// + /// Performance tuned method for use in the tree + /// + /// The parentdocuments id /// - //public object this[string alias] - //{ - // get - // { - // if (this._optimizedMode) - // { - // return this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Value; - // } - // else - // { - // return this.getProperty(alias).Value; - // } - // } - // set - // { - // if (this._optimizedMode) - // { - // if (this._knownProperties.SingleOrDefault(p => propertyTypeByAlias(p, alias)).Key == null) - // { - // var pt = this.getProperty(alias); + public static Document[] GetChildrenForTree(int NodeId) + { + var tmp = new List(); + using (IRecordsReader dr = + SqlHelper.ExecuteReader( + string.Format(m_SQLOptimizedMany, "umbracoNode.parentID = @parentId", "umbracoNode.sortOrder"), + SqlHelper.CreateParameter("@parentId", NodeId))) + { + while (dr.Read()) + { + Document d = new Document(dr.GetInt("id"), true); + d.PopulateDocumentFromReader(dr); + tmp.Add(d); + } + } - // this._knownProperties.Add(pt, pt.Value); - // } - // else - // { - // var pt = this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Key; - // this._knownProperties[pt] = value; - // } - // } - // else - // { - // this.getProperty(alias).Value = value; - // } - // } - //} + return tmp.ToArray(); + } + public static void RePublishAll() + { + XmlDocument xd = new XmlDocument(); + SqlHelper.ExecuteNonQuery("truncate table cmsContentXml"); + IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1"); + + while (dr.Read()) + { + try + { + new Document(dr.GetInt("nodeId")).XmlGenerate(xd); + } + catch (Exception ee) + { + Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"), + string.Format("Error generating xml: {0}", ee)); + } + } + dr.Close(); + } + + public static void RegeneratePreviews() + { + XmlDocument xd = new XmlDocument(); + IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument"); + + while (dr.Read()) + { + try + { + new Document(dr.GetInt("nodeId")).SaveXmlPreview(xd); + } + catch (Exception ee) + { + Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"), + string.Format("Error generating preview xml: {0}", ee)); + } + } + dr.Close(); + } + + /// + /// Retrieve a list of documents with an expirationdate greater than today + /// + /// A list of documents with expirationdates than today + public static Document[] GetDocumentsForExpiration() + { + ArrayList docs = new ArrayList(); + IRecordsReader dr = + SqlHelper.ExecuteReader("select distinct nodeId from cmsDocument where newest = 1 and not expireDate is null and expireDate <= @today", + SqlHelper.CreateParameter("@today", DateTime.Now)); + while (dr.Read()) + docs.Add(dr.GetInt("nodeId")); + dr.Close(); + + Document[] retval = new Document[docs.Count]; + for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); + return retval; + } + + /// + /// Retrieve a list of documents with with releasedate greater than today + /// + /// Retrieve a list of documents with with releasedate greater than today + public static Document[] GetDocumentsForRelease() + { + ArrayList docs = new ArrayList(); + IRecordsReader dr = SqlHelper.ExecuteReader("select distinct nodeId, level, sortOrder from cmsDocument inner join umbracoNode on umbracoNode.id = cmsDocument.nodeId where newest = 1 and not releaseDate is null and releaseDate <= @today order by [level], sortOrder", + SqlHelper.CreateParameter("@today", DateTime.Now)); + while (dr.Read()) + docs.Add(dr.GetInt("nodeId")); + dr.Close(); + + + Document[] retval = new Document[docs.Count]; + for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); + + return retval; + } + + #endregion + + #region Public Properties /// /// Gets a value indicating whether the document was constructed for the optimized mode @@ -307,8 +586,6 @@ namespace umbraco.cms.businesslogic.web get { return _writer; } } - - /// /// The current HTTPContext /// @@ -325,6 +602,176 @@ namespace umbraco.cms.businesslogic.web } } + /// + /// Published flag is on if the document are published + /// + public bool Published + { + get { return _published; } + + set + { + _published = value; + SqlHelper.ExecuteNonQuery( + string.Format("update cmsDocument set published = {0} where nodeId = {1}", Id, value ? 1 : 0)); + } + } + + public override string Text + { + get + { + return base.Text; + } + set + { + base.Text = value; + SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", + SqlHelper.CreateParameter("@text", value), + SqlHelper.CreateParameter("@versionId", Version)); + //CMSNode c = new CMSNode(Id); + //c.Text = value; + } + } + + /// + /// The date of the last update of the document + /// + public DateTime UpdateDate + { + get { return _updated; } + set + { + _updated = value; + SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", + SqlHelper.CreateParameter("@value", value), + SqlHelper.CreateParameter("@versionId", Version)); + } + } + + /// + /// A datestamp which indicates when a document should be published, used in automated publish/unpublish scenarios + /// + public DateTime ReleaseDate + { + get { return _release; } + set + { + _release = value; + + if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) + SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = @value where versionId = @versionId", + SqlHelper.CreateParameter("@value", value), + SqlHelper.CreateParameter("@versionId", Version)); + else + SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = NULL where versionId = @versionId", + SqlHelper.CreateParameter("@versionId", Version)); + } + } + + /// + /// A datestamp which indicates when a document should be unpublished, used in automated publish/unpublish scenarios + /// + public DateTime ExpireDate + { + get { return _expire; } + set + { + _expire = value; + + if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) + SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = @value where versionId=@versionId", + SqlHelper.CreateParameter("@value", value), + SqlHelper.CreateParameter("@versionId", Version)); + else + SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = NULL where versionId=@versionId", + SqlHelper.CreateParameter("@versionId", Version)); + } + } + + /// + /// The id of the template associated to the document + /// + /// When a document is created, it will get have default template given by it's documenttype, + /// an editor is able to assign alternative templates (allowed by it's the documenttype) + /// + /// You are always able to override the template in the runtime by appending the following to the querystring to the Url: + /// + /// ?altTemplate=[templatealias] + /// + public int Template + { + get { return _template; } + set + { + _template = value; + SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", + SqlHelper.CreateParameter("@value", _template), + SqlHelper.CreateParameter("@versionId", Version)); + } + } + + /// + /// A collection of documents imidiately underneath this document ie. the childdocuments + /// + public new Document[] Children + { + get + { + //cache the documents children so that this db call doesn't have to occur again + if (this._children == null) + this._children = Document.GetChildrenForTree(this.Id); + + return this._children.ToArray(); + } + } + + + /// + /// Indexed property to return the property value by name + /// + /// + /// + //public object this[string alias] + //{ + // get + // { + // if (this._optimizedMode) + // { + // return this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Value; + // } + // else + // { + // return this.getProperty(alias).Value; + // } + // } + // set + // { + // if (this._optimizedMode) + // { + // if (this._knownProperties.SingleOrDefault(p => propertyTypeByAlias(p, alias)).Key == null) + // { + // var pt = this.getProperty(alias); + + // this._knownProperties.Add(pt, pt.Value); + // } + // else + // { + // var pt = this._knownProperties.Single(p => propertyTypeByAlias(p, alias)).Key; + // this._knownProperties[pt] = value; + // } + // } + // else + // { + // this.getProperty(alias).Value = value; + // } + // } + //} + + #endregion + + #region Public Methods + /// /// Executes handlers and events for the Send To Publication action. /// @@ -399,7 +846,7 @@ namespace umbraco.cms.businesslogic.web SqlHelper.CreateParameter("@userId", u.Id), SqlHelper.CreateParameter("@versionId", newVersion), SqlHelper.CreateParameter("@text", Text)); - + SqlHelper.ExecuteNonQuery("update cmsDocument set published = 0 where nodeId = " + Id); SqlHelper.ExecuteNonQuery("update cmsDocument set published = 1, newest = 0 where versionId = @versionId", SqlHelper.CreateParameter("@versionId", tempVersion)); @@ -424,7 +871,6 @@ namespace umbraco.cms.businesslogic.web } } - public bool PublishWithChildrenWithResult(User u) { if (PublishWithResult(u)) @@ -531,21 +977,6 @@ namespace umbraco.cms.businesslogic.web } } - /// - /// Published flag is on if the document are published - /// - public bool Published - { - get { return _published; } - - set - { - _published = value; - SqlHelper.ExecuteNonQuery( - string.Format("update cmsDocument set published = {0} where nodeId = {1}", Id, value ? 1 : 0)); - } - } - public void UnPublish() { UnPublishEventArgs e = new UnPublishEventArgs(); @@ -555,9 +986,9 @@ namespace umbraco.cms.businesslogic.web if (!e.Cancel) { SqlHelper.ExecuteNonQuery(string.Format("update cmsDocument set published = 0 where nodeId = {0}", Id)); - + _published = false; - + FireAfterUnPublish(e); } } @@ -592,34 +1023,9 @@ namespace umbraco.cms.businesslogic.web } } - protected override void setupNode() - { - base.setupNode(); - - IRecordsReader dr = - SqlHelper.ExecuteReader("select published, documentUser, coalesce(templateId, cmsDocumentType.templateNodeId) as templateId, text, releaseDate, expireDate, updateDate from cmsDocument inner join cmsContent on cmsDocument.nodeId = cmsContent.Nodeid left join cmsDocumentType on cmsDocumentType.contentTypeNodeId = cmsContent.contentType and cmsDocumentType.IsDefault = 1 where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", Version)); - if (dr.Read()) - { - _creator = User; - _writer = User.GetUser(dr.GetInt("documentUser")); - - if (!dr.IsNull("templateId")) - _template = dr.GetInt("templateId"); - if (!dr.IsNull("releaseDate")) - _release = dr.GetDateTime("releaseDate"); - if (!dr.IsNull("expireDate")) - _expire = dr.GetDateTime("expireDate"); - if (!dr.IsNull("updateDate")) - _updated = dr.GetDateTime("updateDate"); - } - dr.Close(); - _published = HasPublishedVersion(); - } - public bool HasPublishedVersion() { - return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); + return (SqlHelper.ExecuteScalar("select Count(published) as tmp from cmsDocument where published = 1 And nodeId =" + Id) > 0); } /// @@ -633,170 +1039,6 @@ namespace umbraco.cms.businesslogic.web return new TimeSpan(UpdateDate.Ticks - VersionDate.Ticks).TotalMilliseconds > 500; } - protected void InitializeDocument(User InitUser, User InitWriter, string InitText, int InitTemplate, - DateTime InitReleaseDate, DateTime InitExpireDate, DateTime InitUpdateDate, - bool InitPublished) - { - _creator = InitUser; - _writer = InitWriter; - SetText(InitText); - _template = InitTemplate; - _release = InitReleaseDate; - _expire = InitExpireDate; - _updated = InitUpdateDate; - _published = InitPublished; - } - - protected void PopulateDocumentFromReader(IRecordsReader dr) - { - bool _hc = false; - - if (dr.GetInt("children") > 0) - _hc = true; - - int? masterContentType = null; - - if (!dr.IsNull("masterContentType")) - masterContentType = dr.GetInt("masterContentType"); - - SetupDocumentForTree(dr.GetGuid("uniqueId") - , dr.GetShort("level") - , dr.GetInt("parentId") - , dr.GetInt("documentUser") - , (dr.GetInt("published") == 1) - , dr.GetString("path") - , dr.GetString("text") - , dr.GetDateTime("createDate") - , dr.GetDateTime("updateDate") - , dr.GetDateTime("versionDate") - , dr.GetString("icon") - , _hc - , dr.GetString("alias") - , dr.GetString("thumbnail") - , dr.GetString("description") - , masterContentType - , dr.GetInt("contentTypeId") - , dr.GetInt("templateId")); - } - - public override string Text - { - get - { - return base.Text; - } - set - { - base.Text = value; - SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", - SqlHelper.CreateParameter("@text", value), - SqlHelper.CreateParameter("@versionId", Version)); - //CMSNode c = new CMSNode(Id); - //c.Text = value; - } - } - - /// - /// The name of the document, amongst other used in the nice url. - /// - //public new string Text - //{ - // get - // { - // if (_text == null || _text == "") - // _text = SqlHelper.ExecuteScalar(string.Format("select text from umbracoNode where id = {0}", Id)); - // return _text; - // } - // set - // { - // _text = value; - // base.Text = value; - // SqlHelper.ExecuteNonQuery("update cmsDocument set text = @text where versionId = @versionId", - // SqlHelper.CreateParameter("@text", _text), - // SqlHelper.CreateParameter("@versionId", Version)); - // CMSNode c = new CMSNode(Id); - // c.Text = _text; - - // } - //} - - /// - /// The date of the last update of the document - /// - public DateTime UpdateDate - { - get { return _updated; } - set - { - _updated = value; - SqlHelper.ExecuteNonQuery("update cmsDocument set updateDate = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); - } - } - - /// - /// A datestamp which indicates when a document should be published, used in automated publish/unpublish scenarios - /// - public DateTime ReleaseDate - { - get { return _release; } - set - { - _release = value; - - if (_release.Year != 1 || _release.Month != 1 || _release.Day != 1) - SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); - else - SqlHelper.ExecuteNonQuery("update cmsDocument set releaseDate = NULL where versionId = @versionId", - SqlHelper.CreateParameter("@versionId", Version)); - } - } - - /// - /// A datestamp which indicates when a document should be unpublished, used in automated publish/unpublish scenarios - /// - public DateTime ExpireDate - { - get { return _expire; } - set - { - _expire = value; - - if (_expire.Year != 1 || _expire.Month != 1 || _expire.Day != 1) - SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = @value where versionId=@versionId", - SqlHelper.CreateParameter("@value", value), - SqlHelper.CreateParameter("@versionId", Version)); - else - SqlHelper.ExecuteNonQuery("update cmsDocument set expireDate = NULL where versionId=@versionId", - SqlHelper.CreateParameter("@versionId", Version)); - } - } - - /// - /// The id of the template associated to the document - /// - /// When a document is created, it will get have default template given by it's documenttype, - /// an editor is able to assign alternative templates (allowed by it's the documenttype) - /// - /// You are always able to override the template in the runtime by appending the following to the querystring to the Url: - /// - /// ?altTemplate=[templatealias] - /// - public int Template - { - get { return _template; } - set - { - _template = value; - SqlHelper.ExecuteNonQuery("update cmsDocument set templateId = @value where versionId = @versionId", - SqlHelper.CreateParameter("@value", _template), - SqlHelper.CreateParameter("@versionId", Version)); - } - } - /// /// Used for rolling back documents to a previous version /// @@ -868,7 +1110,7 @@ namespace umbraco.cms.businesslogic.web Document NewDoc = MakeNew(Text, new DocumentType(ContentType.Id), u, CopyTo); // update template if a template is set - if (this.Template > 0) + if (this.Template > 0) NewDoc.Template = Template; //update the trashed property as it could be copied inside the recycle bin @@ -900,116 +1142,6 @@ namespace umbraco.cms.businesslogic.web } } - /// - /// Creates a new document - /// - /// The name (.Text property) of the document - /// The documenttype - /// The usercontext under which the action are performed - /// The id of the parent to the document - /// The newly created document - public static Document MakeNew(string Name, DocumentType dct, User u, int ParentId) - { - //allows you to cancel a document before anything goes to the DB - var newingArgs = new DocumentNewingEventArgs() - { - Text = Name, - DocumentType = dct, - User = u, - ParentId = ParentId - }; - Document.OnNewing(newingArgs); - if (newingArgs.Cancel) - { - return null; - } - - - Guid newId = Guid.NewGuid(); - - // Updated to match level from base node - CMSNode n = new CMSNode(ParentId); - int newLevel = n.Level; - newLevel++; - MakeNew(ParentId, _objectType, u.Id, newLevel, Name, newId); - Document tmp = new Document(newId, true); - tmp.CreateContent(dct); - SqlHelper.ExecuteNonQuery("insert into cmsDocument (newest, nodeId, published, documentUser, versionId, Text) values (1, " + - tmp.Id + ", 0, " + - u.Id + ", @versionId, @text)", - SqlHelper.CreateParameter("@versionId", tmp.Version), - SqlHelper.CreateParameter("@text", tmp.Text)); - - // Update the sortOrder if the parent was the root! - if (ParentId == -1) - { - CMSNode c = new CMSNode(newId); - c.sortOrder = GetRootDocuments().Length + 1; - } - - Document d = new Document(newId); - - //event - NewEventArgs e = new NewEventArgs(); - d.OnNew(e); - - // Log - Log.Add(LogTypes.New, u, d.Id, ""); - - // Run Handler - umbraco.BusinessLogic.Actions.Action.RunActionHandlers(d, ActionNew.Instance); - - // Save doc - d.Save(); - - return d; - } - - - /// - /// Used to get the firstlevel/root documents of the hierachy - /// - /// Root documents - public static Document[] GetRootDocuments() - { - Guid[] topNodeIds = TopMostNodeIds(_objectType); - - Document[] retval = new Document[topNodeIds.Length]; - for (int i = 0; i < topNodeIds.Length; i++) - { - Document d = new Document(topNodeIds[i]); - retval[i] = d; - } - return retval; - } - - /// - /// A collection of documents imidiately underneath this document ie. the childdocuments - /// - public new Document[] Children - { - get - { - //cache the documents children so that this db call doesn't have to occur again - if (this._children == null) - this._children = Document.GetChildrenForTree(this.Id); - - return this._children.ToArray(); - } - } - - public static int CountSubs(int parentId, bool publishedOnly) - { - if (!publishedOnly) - { - return CountSubs(parentId); - } - else - { - return SqlHelper.ExecuteScalar("SELECT COUNT(distinct nodeId) FROM umbracoNode INNER JOIN cmsDocument ON cmsDocument.published = 1 and cmsDocument.nodeId = umbracoNode.id WHERE ','+path+',' LIKE '%," + parentId.ToString() + ",%'"); - } - } - /// /// Puts the current document in the trash /// @@ -1034,103 +1166,6 @@ namespace umbraco.cms.businesslogic.web } } - /// - /// Used internally to permanently delete the data from the database - /// - /// - /// if onlyThisDocType is set, this means that we shouldn't delete any children that are not - /// the document type specified and instead just move them to the recycle bin. This is effective if - /// we're deleting an entire document type but don't want to delete other data that isn't this document type - /// but the ndoe exists as a child of the document type that is being deleted. - /// - /// returns true if deletion isn't cancelled - private bool DeletePermanently() - { - DeleteEventArgs e = new DeleteEventArgs(); - - FireBeforeDelete(e); - - if (!e.Cancel) - { - foreach (Document d in Children.ToList()) - { - d.DeletePermanently(); - } - - umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); - - //delete files - interfaces.IDataType uploadField = new cms.businesslogic.datatype.controls.Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")); - var props = this.getProperties; - foreach (Property p in props) - { - if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id && - p.Value.ToString() != "" && - System.IO.File.Exists(IOHelper.MapPath(p.Value.ToString()))) - { - System.IO.File.Delete(IOHelper.MapPath(p.Value.ToString())); - } - } - - //remove any domains associated - var domains = Domain.GetDomainsById(this.Id).ToList(); - domains.ForEach(x => x.Delete()); - - SqlHelper.ExecuteNonQuery("delete from cmsDocument where NodeId = " + Id); - base.delete(); - - FireAfterDelete(e); - } - return !e.Cancel; - } - - /// - /// Used internally to move the node to the recyle bin - /// - /// Returns true if the move was not cancelled - private bool MoveToTrash() - { - MoveToTrashEventArgs e = new MoveToTrashEventArgs(); - FireBeforeMoveToTrash(e); - - if (!e.Cancel) - { - umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); - UnPublish(); - Move((int)RecycleBin.RecycleBinType.Content); - FireAfterMoveToTrash(e); - } - return !e.Cancel; - } - - /// - /// Deletes all documents of a type, will be invoked if a documenttype is deleted. - /// - /// Note: use with care: this method can result in wast amount of data being deleted. - /// - /// The type of which documents should be deleted - public static void DeleteFromType(DocumentType dt) - { - //get all document for the document type and order by level (top level first) - var docs = Document.GetDocumentsOfDocumentType(dt.Id) - .OrderByDescending(x => x.Level); - - foreach (Document doc in docs) - { - //before we delete this document, we need to make sure we don't end up deleting other documents that - //are not of this document type that are children. So we'll move all of it's children to the trash first. - foreach (Document c in doc.GetDescendants()) - { - if (c.ContentType.Id != dt.Id) - { - c.MoveToTrash(); - } - } - - doc.DeletePermanently(); - } - } - /// /// Returns all decendants of the current document /// @@ -1170,7 +1205,7 @@ namespace umbraco.cms.businesslogic.web /// Creates an xmlrepresentation of the document and saves it to the database /// /// - public new void XmlGenerate(XmlDocument xd) + public override void XmlGenerate(XmlDocument xd) { XmlNode x = generateXmlWithoutSaving(xd); /* @@ -1189,28 +1224,6 @@ namespace umbraco.cms.businesslogic.web saveXml(x); } - - private void saveXml(XmlNode x) - { - bool exists = (SqlHelper.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId=@nodeId", - SqlHelper.CreateParameter("@nodeId", Id)) != 0); - string sql = exists ? "UPDATE cmsContentXml SET xml = @xml WHERE nodeId=@nodeId" - : "INSERT INTO cmsContentXml(nodeId, xml) VALUES (@nodeId, @xml)"; - SqlHelper.ExecuteNonQuery(sql, - SqlHelper.CreateParameter("@nodeId", Id), - SqlHelper.CreateParameter("@xml", x.OuterXml)); - } - - private XmlNode importXml() - { - XmlDocument xmlDoc = new XmlDocument(); - XmlReader xmlRdr = SqlHelper.ExecuteXmlReader(string.Format( - "select xml from cmsContentXml where nodeID = {0}", Id)); - xmlDoc.Load(xmlRdr); - - return xmlDoc.FirstChild; - } - /// /// A xmlrepresentaion of the document, used when publishing/exporting the document, /// @@ -1219,7 +1232,7 @@ namespace umbraco.cms.businesslogic.web /// The xmldocument /// Recursive add of childdocuments /// - public new virtual XmlNode ToXml(XmlDocument xd, bool Deep) + public override XmlNode ToXml(XmlDocument xd, bool Deep) { if (Published) { @@ -1240,7 +1253,6 @@ namespace umbraco.cms.businesslogic.web if (Deep) { - //store children array here because iterating over an Array property object is very inneficient. var c = Children; foreach (Document d in c) { @@ -1347,169 +1359,6 @@ namespace umbraco.cms.businesslogic.web } - #region XmlPreivew - - public override XmlNode ToPreviewXml(XmlDocument xd) - { - if (!PreviewExists(Version)) - { - SaveXmlPreview(xd); - } - return GetPreviewXml(xd, Version); - } - - protected void SaveXmlPreview(XmlDocument xd) - { - savePreviewXml(generateXmlWithoutSaving(xd), Version); - } - - #endregion - - private XmlAttribute addAttribute(XmlDocument Xd, string Name, string Value) - { - XmlAttribute temp = Xd.CreateAttribute(Name); - temp.Value = Value; - return temp; - } - - public static IEnumerable GetDocumentsOfDocumentType(int docTypeId) - { - var tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany, "cmsContent.contentType = @contentTypeId", "umbracoNode.sortOrder"), - SqlHelper.CreateParameter("@contentTypeId", docTypeId))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp.ToArray(); - } - - /// - /// Performance tuned method for use in the tree - /// - /// The parentdocuments id - /// - public static Document[] GetChildrenForTree(int NodeId) - { - var tmp = new List(); - using (IRecordsReader dr = - SqlHelper.ExecuteReader( - string.Format(m_SQLOptimizedMany, "umbracoNode.parentID = @parentId", "umbracoNode.sortOrder"), - SqlHelper.CreateParameter("@parentId", NodeId))) - { - while (dr.Read()) - { - Document d = new Document(dr.GetInt("id"), true); - d.PopulateDocumentFromReader(dr); - tmp.Add(d); - } - } - - return tmp.ToArray(); - } - - private void SetupDocumentForTree(Guid uniqueId, int level, int parentId, int user, bool publish, string path, - string text, DateTime createDate, DateTime updateDate, - DateTime versionDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, - string contentTypeDesc, int? masterContentType, int contentTypeId, int templateId) - { - SetupNodeForTree(uniqueId, _objectType, level, parentId, user, path, text, createDate, hasChildren); - - _published = publish; - _updated = updateDate; - _template = templateId; - ContentType = new ContentType(contentTypeId, contentTypeAlias, icon, contentTypeThumb, masterContentType); - ContentTypeIcon = icon; - VersionDate = versionDate; - } - - public static void RePublishAll() - { - XmlDocument xd = new XmlDocument(); - SqlHelper.ExecuteNonQuery("truncate table cmsContentXml"); - IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument where published = 1"); - - while (dr.Read()) - { - try - { - new Document(dr.GetInt("nodeId")).XmlGenerate(xd); - } - catch (Exception ee) - { - Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"), - string.Format("Error generating xml: {0}", ee)); - } - } - dr.Close(); - } - - public static void RegeneratePreviews() - { - XmlDocument xd = new XmlDocument(); - IRecordsReader dr = SqlHelper.ExecuteReader("select nodeId from cmsDocument"); - - while (dr.Read()) - { - try - { - new Document(dr.GetInt("nodeId")).SaveXmlPreview(xd); - } - catch (Exception ee) - { - Log.Add(LogTypes.Error, User.GetUser(0), dr.GetInt("nodeId"), - string.Format("Error generating preview xml: {0}", ee)); - } - } - dr.Close(); - } - - /// - /// Retrieve a list of documents with an expirationdate greater than today - /// - /// A list of documents with expirationdates than today - public static Document[] GetDocumentsForExpiration() - { - ArrayList docs = new ArrayList(); - IRecordsReader dr = - SqlHelper.ExecuteReader("select distinct nodeId from cmsDocument where newest = 1 and not expireDate is null and expireDate <= @today", - SqlHelper.CreateParameter("@today", DateTime.Now)); - while (dr.Read()) - docs.Add(dr.GetInt("nodeId")); - dr.Close(); - - Document[] retval = new Document[docs.Count]; - for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - return retval; - } - - /// - /// Retrieve a list of documents with with releasedate greater than today - /// - /// Retrieve a list of documents with with releasedate greater than today - public static Document[] GetDocumentsForRelease() - { - ArrayList docs = new ArrayList(); - IRecordsReader dr = SqlHelper.ExecuteReader("select distinct nodeId, level, sortOrder from cmsDocument inner join umbracoNode on umbracoNode.id = cmsDocument.nodeId where newest = 1 and not releaseDate is null and releaseDate <= @today order by [level], sortOrder", - SqlHelper.CreateParameter("@today", DateTime.Now)); - while (dr.Read()) - docs.Add(dr.GetInt("nodeId")); - dr.Close(); - - - Document[] retval = new Document[docs.Count]; - for (int i = 0; i < docs.Count; i++) retval[i] = new Document((int)docs[i]); - - return retval; - } - public override List GetNodesForPreview(bool childrenOnly) { List nodes = new List(); @@ -1524,77 +1373,207 @@ namespace umbraco.cms.businesslogic.web return nodes; } - /// - /// Imports (create) a document from a xmlrepresentation of a document, used by the packager - /// - /// The id to import to - /// Creator of the new document - /// Xmlsource - public static int Import(int ParentId, User Creator, XmlElement Source) + public override XmlNode ToPreviewXml(XmlDocument xd) { - Document d = MakeNew( - Source.GetAttribute("nodeName"), - DocumentType.GetByAlias(Source.GetAttribute("nodeTypeAlias")), - Creator, - ParentId); - - d.CreateDateTime = DateTime.Parse(Source.GetAttribute("createDate")); - - // Properties - foreach (XmlElement n in Source.SelectNodes("data")) + if (!PreviewExists(Version)) { - Property prop = d.getProperty(n.GetAttribute("alias")); - string propValue = xmlHelper.GetNodeValue(n); - - // only update real values - if (!String.IsNullOrEmpty(propValue)) - { - //test if the property has prevalues, of so, try to convert the imported values so they match the new ones - SortedList prevals = cms.businesslogic.datatype.PreValues.GetPreValues(prop.PropertyType.DataTypeDefinition.Id); - - //Okey we found some prevalue, let's replace the vals with some ids - if (prevals.Count > 0) - { - System.Collections.Generic.List list = new System.Collections.Generic.List(propValue.Split(',')); - - foreach (DictionaryEntry item in prevals) - { - string pval = ((umbraco.cms.businesslogic.datatype.PreValue)item.Value).Value; - string pid = ((umbraco.cms.businesslogic.datatype.PreValue)item.Value).Id.ToString(); - - if (list.Contains(pval)) - list[list.IndexOf(pval)] = pid; - - } - - //join the list of new values and return it as the new property value - System.Text.StringBuilder builder = new System.Text.StringBuilder(); - bool isFirst = true; - - foreach (string str in list) - { - if (!isFirst) - builder.Append(","); - - builder.Append(str); - isFirst = false; - } - prop.Value = builder.ToString(); - - } - else - prop.Value = propValue; - } + SaveXmlPreview(xd); } - - // Subpages - foreach (XmlElement n in Source.SelectNodes("node")) - Import(d.Id, Creator, n); - - return d.Id; + return GetPreviewXml(xd, Version); } - //EVENTS + #endregion + + #region Protected Methods + protected override void setupNode() + { + base.setupNode(); + + IRecordsReader dr = + SqlHelper.ExecuteReader("select published, documentUser, coalesce(templateId, cmsDocumentType.templateNodeId) as templateId, text, releaseDate, expireDate, updateDate from cmsDocument inner join cmsContent on cmsDocument.nodeId = cmsContent.Nodeid left join cmsDocumentType on cmsDocumentType.contentTypeNodeId = cmsContent.contentType and cmsDocumentType.IsDefault = 1 where versionId = @versionId", + SqlHelper.CreateParameter("@versionId", Version)); + if (dr.Read()) + { + _creator = User; + _writer = User.GetUser(dr.GetInt("documentUser")); + + if (!dr.IsNull("templateId")) + _template = dr.GetInt("templateId"); + if (!dr.IsNull("releaseDate")) + _release = dr.GetDateTime("releaseDate"); + if (!dr.IsNull("expireDate")) + _expire = dr.GetDateTime("expireDate"); + if (!dr.IsNull("updateDate")) + _updated = dr.GetDateTime("updateDate"); + } + dr.Close(); + _published = HasPublishedVersion(); + } + + protected void InitializeDocument(User InitUser, User InitWriter, string InitText, int InitTemplate, + DateTime InitReleaseDate, DateTime InitExpireDate, DateTime InitUpdateDate, + bool InitPublished) + { + _creator = InitUser; + _writer = InitWriter; + SetText(InitText); + _template = InitTemplate; + _release = InitReleaseDate; + _expire = InitExpireDate; + _updated = InitUpdateDate; + _published = InitPublished; + } + + protected void PopulateDocumentFromReader(IRecordsReader dr) + { + bool _hc = false; + + if (dr.GetInt("children") > 0) + _hc = true; + + int? masterContentType = null; + + if (!dr.IsNull("masterContentType")) + masterContentType = dr.GetInt("masterContentType"); + + SetupDocumentForTree(dr.GetGuid("uniqueId") + , dr.GetShort("level") + , dr.GetInt("parentId") + , dr.GetInt("documentUser") + , (dr.GetInt("published") == 1) + , dr.GetString("path") + , dr.GetString("text") + , dr.GetDateTime("createDate") + , dr.GetDateTime("updateDate") + , dr.GetDateTime("versionDate") + , dr.GetString("icon") + , _hc + , dr.GetString("alias") + , dr.GetString("thumbnail") + , dr.GetString("description") + , masterContentType + , dr.GetInt("contentTypeId") + , dr.GetInt("templateId")); + } + + protected void SaveXmlPreview(XmlDocument xd) + { + savePreviewXml(generateXmlWithoutSaving(xd), Version); + } + + #endregion + + #region Private Methods + private void SetupDocumentForTree(Guid uniqueId, int level, int parentId, int user, bool publish, string path, + string text, DateTime createDate, DateTime updateDate, + DateTime versionDate, string icon, bool hasChildren, string contentTypeAlias, string contentTypeThumb, + string contentTypeDesc, int? masterContentType, int contentTypeId, int templateId) + { + SetupNodeForTree(uniqueId, _objectType, level, parentId, user, path, text, createDate, hasChildren); + + _published = publish; + _updated = updateDate; + _template = templateId; + ContentType = new ContentType(contentTypeId, contentTypeAlias, icon, contentTypeThumb, masterContentType); + ContentTypeIcon = icon; + VersionDate = versionDate; + } + + private XmlAttribute addAttribute(XmlDocument Xd, string Name, string Value) + { + XmlAttribute temp = Xd.CreateAttribute(Name); + temp.Value = Value; + return temp; + } + + private void saveXml(XmlNode x) + { + bool exists = (SqlHelper.ExecuteScalar("SELECT COUNT(nodeId) FROM cmsContentXml WHERE nodeId=@nodeId", + SqlHelper.CreateParameter("@nodeId", Id)) != 0); + string sql = exists ? "UPDATE cmsContentXml SET xml = @xml WHERE nodeId=@nodeId" + : "INSERT INTO cmsContentXml(nodeId, xml) VALUES (@nodeId, @xml)"; + SqlHelper.ExecuteNonQuery(sql, + SqlHelper.CreateParameter("@nodeId", Id), + SqlHelper.CreateParameter("@xml", x.OuterXml)); + } + + private XmlNode importXml() + { + XmlDocument xmlDoc = new XmlDocument(); + XmlReader xmlRdr = SqlHelper.ExecuteXmlReader(string.Format( + "select xml from cmsContentXml where nodeID = {0}", Id)); + xmlDoc.Load(xmlRdr); + + return xmlDoc.FirstChild; + } + + /// + /// Used internally to permanently delete the data from the database + /// + /// returns true if deletion isn't cancelled + private bool DeletePermanently() + { + DeleteEventArgs e = new DeleteEventArgs(); + + FireBeforeDelete(e); + + if (!e.Cancel) + { + foreach (Document d in Children.ToList()) + { + d.DeletePermanently(); + } + + umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); + + //delete files + interfaces.IDataType uploadField = new cms.businesslogic.datatype.controls.Factory().GetNewObject(new Guid("5032a6e6-69e3-491d-bb28-cd31cd11086c")); + var props = this.getProperties; + foreach (Property p in props) + { + if (p.PropertyType.DataTypeDefinition.DataType.Id == uploadField.Id && + p.Value.ToString() != "" && + System.IO.File.Exists(IOHelper.MapPath(p.Value.ToString()))) + { + System.IO.File.Delete(IOHelper.MapPath(p.Value.ToString())); + } + } + + //remove any domains associated + var domains = Domain.GetDomainsById(this.Id).ToList(); + domains.ForEach(x => x.Delete()); + + SqlHelper.ExecuteNonQuery("delete from cmsDocument where NodeId = " + Id); + base.delete(); + + FireAfterDelete(e); + } + return !e.Cancel; + } + + /// + /// Used internally to move the node to the recyle bin + /// + /// Returns true if the move was not cancelled + private bool MoveToTrash() + { + MoveToTrashEventArgs e = new MoveToTrashEventArgs(); + FireBeforeMoveToTrash(e); + + if (!e.Cancel) + { + umbraco.BusinessLogic.Actions.Action.RunActionHandlers(this, ActionDelete.Instance); + UnPublish(); + Move((int)RecycleBin.RecycleBinType.Content); + FireAfterMoveToTrash(e); + } + return !e.Cancel; + } + + #endregion + + #region Events + /// /// The save event handler /// @@ -1633,7 +1612,6 @@ namespace umbraco.cms.businesslogic.web /// public delegate void MoveToTrashEventHandler(Document sender, MoveToTrashEventArgs e); - /// /// Occurs when [before save]. /// @@ -1666,7 +1644,6 @@ namespace umbraco.cms.businesslogic.web } } - /// /// Occurs when [new]. /// @@ -1887,7 +1864,8 @@ namespace umbraco.cms.businesslogic.web { if (AfterRollBack != null) AfterRollBack(this, e); - } + } + #endregion } diff --git a/umbraco/cms/umbraco.cms.csproj b/umbraco/cms/umbraco.cms.csproj index 5c90c07ef5..9f52040c76 100644 --- a/umbraco/cms/umbraco.cms.csproj +++ b/umbraco/cms/umbraco.cms.csproj @@ -34,7 +34,7 @@ v3.5 - bin\ + bin\Debug\ false 285212672 false diff --git a/umbraco/presentation/umbraco/create/memberTasks.cs b/umbraco/presentation/umbraco/create/memberTasks.cs index 3e9d6ea3ae..559c37757e 100644 --- a/umbraco/presentation/umbraco/create/memberTasks.cs +++ b/umbraco/presentation/umbraco/create/memberTasks.cs @@ -16,7 +16,7 @@ namespace umbraco /// new public delegate void NewUIMemberEventHandler(Member sender, string unencryptedPassword, NewMemberUIEventArgs e); - new public static event NewUIMemberEventHandler NewMember; + public static event NewUIMemberEventHandler NewMember; new protected virtual void OnNewMember(NewMemberUIEventArgs e, string unencryptedPassword, Member m) { if (NewMember != null) diff --git a/umbraco/presentation/umbraco/masterpages/umbracoDialog.Master.cs b/umbraco/presentation/umbraco/masterpages/umbracoDialog.Master.cs index a99be9d431..d66b3fd29f 100644 --- a/umbraco/presentation/umbraco/masterpages/umbracoDialog.Master.cs +++ b/umbraco/presentation/umbraco/masterpages/umbracoDialog.Master.cs @@ -8,7 +8,7 @@ namespace umbraco.presentation.masterpages { public partial class umbracoDialog : System.Web.UI.MasterPage { public bool reportModalSize { get; set; } - public static event MasterPageLoadHandler Load; + public static new event MasterPageLoadHandler Load; public static event MasterPageLoadHandler Init; protected void Page_Load(object sender, EventArgs e) diff --git a/umbraco/presentation/web.STANDARD.config b/umbraco/presentation/web.STANDARD.config index b48af3418b..259a951ae7 100644 --- a/umbraco/presentation/web.STANDARD.config +++ b/umbraco/presentation/web.STANDARD.config @@ -19,8 +19,8 @@
-
-
+
+