diff --git a/src/Umbraco.Core/Configuration/GlobalSettings.cs b/src/Umbraco.Core/Configuration/GlobalSettings.cs index 5d7845bb68..b837293016 100644 --- a/src/Umbraco.Core/Configuration/GlobalSettings.cs +++ b/src/Umbraco.Core/Configuration/GlobalSettings.cs @@ -201,6 +201,31 @@ namespace Umbraco.Core.Configuration } } + /// + /// Returns the configuration status version as a versoin object or null if it cannot parse + /// + /// + internal static Version GetConfigurationVersion() + { + //create a real version out of the one stored in the settings + var configVersion = ConfigurationStatus.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + if (configVersion.Length == 0) + return null; + + int major; + var minor = 0; + var patch = 0; + int currentPart; + if (configVersion.Length > 0 && int.TryParse(configVersion[0], out currentPart)) + major = currentPart; + else + return null; //couldn't parse, no valid version + if (configVersion.Length > 1 && int.TryParse(configVersion[1], out currentPart)) minor = currentPart; + if (configVersion.Length > 2 && int.TryParse(configVersion[2], out currentPart)) patch = currentPart; + + return new Version(major, minor, patch); + } + /// /// Saves a setting into the configuration file. /// diff --git a/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs b/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs new file mode 100644 index 0000000000..daf95b2241 --- /dev/null +++ b/src/Umbraco.Tests/Install/UpgradeScriptsTests.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using NUnit.Framework; +using Umbraco.Web.Install.UpgradeScripts; + +namespace Umbraco.Tests.Install +{ + [TestFixture] + public class UpgradeScriptsTests + { + [TearDown] + public void TearDown() + { + UpgradeScriptManager.Clear(); + } + + [TestCase("0.0.0", "6.0.0", "4.10.0", true)] + [TestCase("4.10.0", "6.0.0", "4.10.0", true)] + [TestCase("4.10.0", "4.11.4", "4.10.0", true)] + [TestCase("4.11.0", "4.11.4", "4.10.0", false)] + [TestCase("4.11.0", "6.0.0", "4.10.0", false)] + [TestCase("6.0.0", "6.0.0", "6.0.0", false)] //this is not in range because it is up to 6.0 but not including 6.0 + [TestCase("6.0.0", "6.0.0", "6.0.1", false)] + public void Test_Version_Range(string startVersion, string endVersion, string current, bool inRange) + { + var currVersionParts = current.Split('.').Select(int.Parse).ToArray(); + var currentVersion = new Version(currVersionParts[0], currVersionParts[1], currVersionParts[2]); + + var startVersionParts = startVersion.Split('.').Select(int.Parse).ToArray(); + var endVersionParts = endVersion.Split('.').Select(int.Parse).ToArray(); + + UpgradeScriptManager.AddUpgradeScript( + () => new UpgradeScript1(), + new VersionRange( + new Version(startVersionParts[0], startVersionParts[1], startVersionParts[2]), + new Version(endVersionParts[0], endVersionParts[1], endVersionParts[2]))); + + Assert.AreEqual(inRange, UpgradeScriptManager.HasScriptsForVersion(currentVersion)); + } + + [Test] + public void Test_Specific_Version() + { + var currentVersion = new Version(4, 10, 0); + + UpgradeScriptManager.AddUpgradeScript( + () => new UpgradeScript1(), + new VersionRange( + new Version(4, 10, 0))); + + Assert.IsTrue(UpgradeScriptManager.HasScriptsForVersion(currentVersion)); + Assert.IsFalse(UpgradeScriptManager.HasScriptsForVersion(new Version(4, 10, 11))); + Assert.IsFalse(UpgradeScriptManager.HasScriptsForVersion(new Version(4, 11, 0))); + } + + public class UpgradeScript1 : IUpgradeScript + { + public void Execute() + { + Debug.WriteLine("Executing!"); + } + } + + } +} diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs index b09cee1c7a..9657ed0493 100644 --- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs @@ -68,7 +68,8 @@ namespace Umbraco.Tests.Routing } //test all template name styles to match the ActionName - [TestCase("home-page")] + [TestCase("home-\\234^^*32page")] + [TestCase("home-page")] [TestCase("home-\\234^^*32page")] [TestCase("home-page")] [TestCase("home-page")] diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj index d8f16edbd6..1547e770e8 100644 --- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj +++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj @@ -275,6 +275,13 @@ loadStarterKits.ascx + + UpgradeScripts.ascx + ASPXCodeBehind + + + UpgradeScripts.ascx + PartialViewMacro.ascx diff --git a/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx new file mode 100644 index 0000000000..2728a12f66 --- /dev/null +++ b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx @@ -0,0 +1,14 @@ +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="UpgradeScripts.ascx.cs" Inherits="Umbraco.Web.UI.Install.Steps.UpgradeScripts" %> +
+
+

Upgrade scripts

+

+ We need to run a few upgrade scripts, press Continue to execute these scripts and continue to the next step. +

+
+ +
+
 
+ Continue +
+
\ No newline at end of file diff --git a/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs new file mode 100644 index 0000000000..0d94b30821 --- /dev/null +++ b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web; +using System.Web.UI; +using System.Web.UI.WebControls; +using Umbraco.Core.Configuration; +using umbraco.presentation.install; +using Umbraco.Web.Install.UpgradeScripts; + +namespace Umbraco.Web.UI.Install.Steps +{ + public partial class UpgradeScripts : System.Web.UI.UserControl + { + protected void Page_Load(object sender, EventArgs e) + { + + } + + protected void RunScripts(object sender, EventArgs e) + { + //run the scripts and then go to the next step + UpgradeScriptManager.ExecuteScriptsForVersion(GlobalSettings.GetConfigurationVersion()); + + Helper.RedirectToNextStep(Page); + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs new file mode 100644 index 0000000000..a55927fd35 --- /dev/null +++ b/src/Umbraco.Web.UI/install/steps/UpgradeScripts.ascx.designer.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Umbraco.Web.UI.Install.Steps { + + + public partial class UpgradeScripts { + + /// + /// btnNext control. + /// + /// + /// Auto-generated field. + /// To modify move field declaration from designer file to code-behind file. + /// + protected global::System.Web.UI.WebControls.LinkButton btnNext; + } +} diff --git a/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx b/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx index 2650140730..d70e8c59c4 100644 --- a/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx +++ b/src/Umbraco.Web.UI/umbraco/plugins/uGoLive/Dashboard.ascx @@ -1,4 +1,4 @@ -<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Dashboard.ascx.cs" Inherits="Our.Umbraco.uGoLive.Web.Umbraco.Plugins.uGoLive.Dashboard" %> +<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Dashboard.ascx.cs" Inherits="Our.Umbraco.uGoLive.Web.Umbraco.Plugins.uGoLive.Dashboard" %> <%@ Import Namespace="umbraco.IO" %> <%@ Import Namespace="Our.Umbraco.uGoLive.Web" %> <%@ Register Namespace="ClientDependency.Core.Controls" Assembly="ClientDependency.Core" TagPrefix="cdf" %> diff --git a/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs b/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs new file mode 100644 index 0000000000..f52ae5078d --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/ContentPathFix.cs @@ -0,0 +1,130 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Umbraco.Core; +using Umbraco.Core.IO; +using umbraco.cms.businesslogic; +using umbraco.cms.businesslogic.web; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + /// + /// An upgrade script to fix a moving issue in 4.10+ + /// http://issues.umbraco.org/issue/U4-1491 + /// + public class ContentPathFix : IUpgradeScript + { + private readonly StringBuilder _report = new StringBuilder(); + + public void Execute() + { + //return; + if (ApplicationContext.Current == null) return; + if (HasBeenFixed()) return; + Fix(); + WriteReport(); + } + + private void Fix() + { + AddReportLine("Starting fix paths script"); + + //fix content + AddReportLine("Fixing content"); + foreach (var d in Document.GetRootDocuments()) + { + FixPathsForChildren(d, content => ((Document)content).Children); + } + AddReportLine("Fixing content recycle bin"); + var contentRecycleBin = new RecycleBin(RecycleBin.RecycleBinType.Content); + foreach (var d in contentRecycleBin.Children) + { + FixPathsForChildren(new Document(d.Id), content => ((Document)content).Children); + } + + //fix media + AddReportLine("Fixing media"); + foreach (var d in global::umbraco.cms.businesslogic.media.Media.GetRootMedias()) + { + FixPathsForChildren(d, media => ((global::umbraco.cms.businesslogic.media.Media)media).Children); + } + AddReportLine("Fixing media recycle bin"); + var mediaRecycleBin = new RecycleBin(RecycleBin.RecycleBinType.Media); + foreach (var d in mediaRecycleBin.Children) + { + FixPathsForChildren(new global::umbraco.cms.businesslogic.media.Media(d.Id), media => ((global::umbraco.cms.businesslogic.media.Media)media).Children); + } + AddReportLine("Complete!"); + } + + /// + /// Returns true if this script has run based on a temp file written to + /// ~/App_Data/TEMP/FixPaths/report.txt + /// + /// + private bool HasBeenFixed() + { + return File.Exists(IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt")); + } + + /// + /// Creates the report + /// + private void WriteReport() + { + var filePath = IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt"); + Directory.CreateDirectory(Path.GetDirectoryName(filePath)); + using (var writer = File.CreateText(IOHelper.MapPath("~/App_Data/TEMP/FixPaths/report.txt"))) + { + writer.Write(_report.ToString()); + } + } + + /// + /// Recursively iterates over the children of the document and fixes the path + /// + /// + /// Callback to get the children of the conent item + /// + /// We cannot use GetDescendants() because that is based on the paths of documents and if they are invalid then + /// we cannot use that method. + /// + private void FixPathsForChildren(Content d, Func> getChildren) + { + AddReportLine("Fixing paths for children of " + d.Id); + foreach (var c in getChildren(d)) + { + FixPath(c); + if (c.HasChildren) + { + FixPathsForChildren(c, getChildren); + } + } + } + + /// + /// Check if the path is correct based on the document's parent if it is not correct, then fix it + /// + /// + private void FixPath(CMSNode d) + { + AddReportLine("Checking path for " + d.Id + ". Current = " + d.Path); + //check if the path is correct + var correctpath = d.Parent.Path + "," + d.Id.ToString(); + if (d.Path != correctpath) + { + AddReportLine(" INVALID PATH DETECTED. Path for " + d.Id + " changed to: " + d.Parent.Path + "," + d.Id.ToString()); + d.Path = correctpath; + d.Level = d.Parent.Level + 1; + } + } + + private void AddReportLine(string str) + { + _report.AppendLine(string.Format("{0} - " + str, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff"))); + } + + + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs b/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs new file mode 100644 index 0000000000..339dbd4ac2 --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/IUpgradeScript.cs @@ -0,0 +1,7 @@ +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal interface IUpgradeScript + { + void Execute(); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs new file mode 100644 index 0000000000..472415598d --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptManager.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Umbraco.Core.Configuration; +using umbraco.DataLayer.Utility.Installer; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + /// + /// Class used to register and execute upgrade scripts during install if they are required. + /// + internal static class UpgradeScriptManager + { + /// + /// Returns true if there are scripts to execute for the version + /// + /// + /// + public static bool HasScriptsForVersion(Version version) + { + return Scripts.Any(x => x.Item2.InRange(version)); + } + + /// + /// Executes all of the scripts for a database version + /// + /// + /// + public static void ExecuteScriptsForVersion(Version version) + { + var types = Scripts.Where(x => x.Item2.InRange(version)).Select(x => x.Item1); + foreach (var instance in types.Select(x => x())) + { + instance.Execute(); + } + } + + public static void AddUpgradeScript(Func script, VersionRange version) + { + Scripts.Add(new Tuple, VersionRange>(script, version)); + } + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(string assemblyQualifiedTypeName, VersionRange version) + //{ + // AddUpgradeScript(new Lazy(() => Type.GetType(assemblyQualifiedTypeName)), version); + //} + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(VersionRange version) + //{ + // AddUpgradeScript(new Lazy(() => typeof(T)), version); + //} + + /// + /// Used for testing + /// + internal static void Clear() + { + Scripts.Clear(); + } + + ///// + ///// Adds a script to execute for a database version + ///// + ///// + ///// + //public static void AddUpgradeScript(Lazy type, VersionRange version) + //{ + // Scripts.Add(new Tuple, VersionRange>(type, version)); + //} + + private static readonly List, VersionRange>> Scripts = new List, VersionRange>>(); + //private static readonly List, VersionRange>> Scripts = new List, VersionRange>>(); + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs new file mode 100644 index 0000000000..611703b7d8 --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/UpgradeScriptRegistrar.cs @@ -0,0 +1,28 @@ +using System; +using Umbraco.Core; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal class UpgradeScriptRegistrar : IApplicationEventHandler + { + public void OnApplicationInitialized(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + //Add contnet path fixup for any version from 4.10 up to 4.11.4 + UpgradeScriptManager.AddUpgradeScript( + () => new ContentPathFix(), + new VersionRange( + new Version(4, 10), + new Version(4, 11, 4))); + } + + public void OnApplicationStarting(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + + } + + public void OnApplicationStarted(UmbracoApplication httpApplication, ApplicationContext applicationContext) + { + + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs b/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs new file mode 100644 index 0000000000..adafd7691a --- /dev/null +++ b/src/Umbraco.Web/Install/UpgradeScripts/VersionRange.cs @@ -0,0 +1,40 @@ +using System; + +namespace Umbraco.Web.Install.UpgradeScripts +{ + internal class VersionRange + { + private readonly Version _specificVersion; + private readonly Version _startVersion; + private readonly Version _endVersion; + + public VersionRange(Version specificVersion) + { + _specificVersion = specificVersion; + } + + public VersionRange(Version startVersion, Version endVersion) + { + _startVersion = startVersion; + _endVersion = endVersion; + } + + /// + /// Checks if the versionCheck is in the range (in between) the start and end version + /// + /// + /// + /// + /// For example if our version range is 4.10 -> 4.11.4, we want to return true if the version being checked is: + /// greater than or equal to the start version but less than the end version. + /// + public bool InRange(Version versionCheck) + { + //if it is a specific version + if (_specificVersion != null) + return versionCheck == _specificVersion; + + return versionCheck >= _startVersion && versionCheck < _endVersion; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Properties/AssemblyInfo.cs b/src/Umbraco.Web/Properties/AssemblyInfo.cs index 42c2237380..c2cb1294a9 100644 --- a/src/Umbraco.Web/Properties/AssemblyInfo.cs +++ b/src/Umbraco.Web/Properties/AssemblyInfo.cs @@ -30,4 +30,6 @@ using System.Security; [assembly: InternalsVisibleTo("Umbraco.Tests")] [assembly: InternalsVisibleTo("umbraco.MacroEngines")] [assembly: InternalsVisibleTo("Umbraco.Web.UI")] -[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")] \ No newline at end of file +[assembly: InternalsVisibleTo("Umbraco.Courier.Persistence")] +[assembly: InternalsVisibleTo("umbraco.webservices")] + diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 24cc484f92..cac8e5c3f6 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -257,6 +257,11 @@ + + + + + @@ -346,6 +351,7 @@ ASPXCodeBehind + ASPXCodeBehind @@ -1913,7 +1919,9 @@ ASPXCodeBehind - + + ASPXCodeBehind + diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index 2c7fd2d023..5ea02da00e 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -10,6 +10,7 @@ using Umbraco.Core.Dynamics; using Umbraco.Core.ObjectResolution; using Umbraco.Core.PropertyEditors; using Umbraco.Web.Dictionary; +using Umbraco.Web.Install.UpgradeScripts; using Umbraco.Web.Media; using Umbraco.Web.Media.ThumbnailProviders; using Umbraco.Web.Models; @@ -70,6 +71,7 @@ namespace Umbraco.Web //set model binder ModelBinders.Binders.Add(new KeyValuePair(typeof(RenderModel), new RenderModelBinder())); + ApplicationEventsResolver.Current.AddType(); return this; } diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index 70d1a2d3e6..8d8dfa0ef2 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -580,40 +580,42 @@ namespace umbraco ThreadPool.QueueUserWorkItem(delegate { UpdateDocumentCache(documentId); }); } - - [Obsolete("Method obsolete in version 4.1 and later, please use ClearDocumentCache", true)] /// /// Clears the document cache async. /// /// The document id. + [Obsolete("Method obsolete in version 4.1 and later, please use ClearDocumentCache", true)] public virtual void ClearDocumentCacheAsync(int documentId) { ThreadPool.QueueUserWorkItem(delegate { ClearDocumentCache(documentId); }); } + public virtual void ClearDocumentCache(int documentId) + { + // Get the document + var d = new Document(documentId); + ClearDocumentCache(d); + } /// /// Clears the document cache and removes the document from the xml db cache. /// This means the node gets unpublished from the website. /// - /// The document id. - public virtual void ClearDocumentCache(int documentId) + /// The document + internal void ClearDocumentCache(Document doc) { - // Get the document - var d = new Document(documentId); - var e = new DocumentCacheEventArgs(); - FireBeforeClearDocumentCache(d, e); + FireBeforeClearDocumentCache(doc, e); if (!e.Cancel) { XmlNode x; // remove from xml db cache - d.XmlRemoveFromDB(); + doc.XmlRemoveFromDB(); // Check if node present, before cloning - x = XmlContentInternal.GetElementById(d.Id.ToString()); + x = XmlContentInternal.GetElementById(doc.Id.ToString()); if (x == null) return; @@ -626,7 +628,7 @@ namespace umbraco XmlDocument xmlContentCopy = CloneXmlDoc(XmlContentInternal); // Find the document in the xml cache - x = xmlContentCopy.GetElementById(d.Id.ToString()); + x = xmlContentCopy.GetElementById(doc.Id.ToString()); if (x != null) { // The document already exists in cache, so repopulate it @@ -639,17 +641,17 @@ namespace umbraco if (x != null) { // Run Handler - Action.RunActionHandlers(d, ActionUnPublish.Instance); + Action.RunActionHandlers(doc, ActionUnPublish.Instance); } // update sitemapprovider if (SiteMap.Provider is UmbracoSiteMapProvider) { var prov = (UmbracoSiteMapProvider)SiteMap.Provider; - prov.RemoveNode(d.Id); + prov.RemoveNode(doc.Id); } - FireAfterClearDocumentCache(d, e); + FireAfterClearDocumentCache(doc, e); } } diff --git a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs index 1bd81f7df3..16ceb1195f 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/default.aspx.cs @@ -9,7 +9,7 @@ using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Collections.Specialized; -using umbraco.IO; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; using System.Collections.Generic; @@ -36,7 +36,7 @@ namespace umbraco.presentation.install private void loadContent(InstallerStep currentStep) { PlaceHolderStep.Controls.Clear(); - PlaceHolderStep.Controls.Add(new System.Web.UI.UserControl().LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); + PlaceHolderStep.Controls.Add(LoadControl(IOHelper.ResolveUrl(currentStep.UserControl))); step.Value = currentStep.Alias; currentStepClass = currentStep.Alias; } @@ -136,6 +136,7 @@ namespace umbraco.presentation.install ics.Add(new install.steps.Definitions.Welcome()); ics.Add(new install.steps.Definitions.License()); ics.Add(new install.steps.Definitions.FilePermissions()); + ics.Add(new install.steps.Definitions.UpgradeScripts()); ics.Add(new install.steps.Definitions.Database()); ics.Add(new install.steps.Definitions.DefaultUser()); ics.Add(new install.steps.Definitions.Skinning()); diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs index f5a695e8cf..8377000db7 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/Database.cs @@ -1,8 +1,8 @@ -using System; -using Umbraco.Core; +using Umbraco.Core; using Umbraco.Core.Configuration; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; -using umbraco.IO; + namespace umbraco.presentation.install.steps.Definitions { @@ -42,6 +42,7 @@ namespace umbraco.presentation.install.steps.Definitions var result = ApplicationContext.Current.DatabaseContext.ValidateDatabaseSchema(); var determinedVersion = result.DetermineInstalledVersion(); if (determinedVersion.Equals(new Version(0, 0, 0))) + { return false; return UmbracoVersion.Current < determinedVersion; diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs index ef3827225f..f0f6887ed3 100644 --- a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/FilePermissions.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using Umbraco.Core.IO; using umbraco.cms.businesslogic.installer; namespace umbraco.presentation.install.steps.Definitions @@ -20,7 +21,7 @@ namespace umbraco.presentation.install.steps.Definitions public override string UserControl { - get { return IO.SystemDirectories.Install + "/steps/validatepermissions.ascx"; } + get { return SystemDirectories.Install + "/steps/validatepermissions.ascx"; } } public override bool HideFromNavigation { diff --git a/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs new file mode 100644 index 0000000000..57d4cf9d9b --- /dev/null +++ b/src/Umbraco.Web/umbraco.presentation/install/steps/Definitions/UpgradeScripts.cs @@ -0,0 +1,78 @@ +using System; +using Umbraco.Core; +using Umbraco.Core.IO; +using Umbraco.Web.Install.UpgradeScripts; +using umbraco.DataLayer.Utility.Installer; +using umbraco.cms.businesslogic.installer; + +namespace umbraco.presentation.install.steps.Definitions +{ + internal class UpgradeScripts : InstallerStep + { + + + + public override string Alias + { + get { return "upgradeScripts"; } + } + + public override bool HideFromNavigation + { + get { return true; } + } + + /// + /// If there are no scripts for this version the skip + /// + /// + public override bool Completed() + { + var canConnect = CanConnectToDb(); + //if we cannot connect to the db, then we cannot run the script and most likely the database doesn't exist yet anyways. + if (!canConnect) return true; //skip + + //if the version is empty then it's probably a new installation, we cannot run scripts + if (GlobalSettings.CurrentVersion.IsNullOrWhiteSpace()) return true; //skip + var currentUmbVersion = Umbraco.Core.Configuration.GlobalSettings.GetConfigurationVersion(); + if (currentUmbVersion == null) + return true; //skip, could not get a version + + //check if we have upgrade script to run for this version + var hasScripts = UpgradeScriptManager.HasScriptsForVersion(currentUmbVersion); + return !hasScripts; + } + + public override string Name + { + get { return "Upgrade scripts"; } + } + + public override string UserControl + { + get { return SystemDirectories.Install + "/steps/UpgradeScripts.ascx"; } + } + + public override bool MoveToNextStepAutomaticly + { + get + { + return true; + } + } + + private bool CanConnectToDb() + { + try + { + var installer = BusinessLogic.Application.SqlHelper.Utility.CreateInstaller(); + var latest = installer.IsLatestVersion; + return true; //if we got this far, we can connect. + } + catch + { + return false; + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/library.cs b/src/Umbraco.Web/umbraco.presentation/library.cs index 1c64fbc96a..2d45157eb3 100644 --- a/src/Umbraco.Web/umbraco.presentation/library.cs +++ b/src/Umbraco.Web/umbraco.presentation/library.cs @@ -188,9 +188,7 @@ namespace umbraco /// /// The Id of the Document to be unpublished public static void UnPublishSingleNode(int DocumentId) - { - - //PPH Added dispatcher support + { if (UmbracoSettings.UseDistributedCalls) dispatcher.Remove( new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), @@ -199,6 +197,21 @@ namespace umbraco content.Instance.ClearDocumentCache(DocumentId); } + /// + /// Unpublish a node, by removing it from the runtime xml index. Note, prior to this the Document should be + /// marked unpublished by setting the publish property on the document object to false + /// + /// The Document to be unpublished + internal static void UnPublishSingleNode(Document document) + { + if (UmbracoSettings.UseDistributedCalls) + dispatcher.Remove( + new Guid("27ab3022-3dfa-47b6-9119-5945bc88fd66"), + document.Id); + else + content.Instance.ClearDocumentCache(document); + } + /// /// Publishes a Document by adding it to the runtime xml index. Note, prior to this the Document should be /// marked published by calling Publish(User u) on the document object. diff --git a/src/Umbraco.Web/umbraco.presentation/publishingService.cs b/src/Umbraco.Web/umbraco.presentation/publishingService.cs index 1f7c6c7c2c..f1d30e7005 100644 --- a/src/Umbraco.Web/umbraco.presentation/publishingService.cs +++ b/src/Umbraco.Web/umbraco.presentation/publishingService.cs @@ -38,7 +38,7 @@ namespace umbraco.presentation d.ReleaseDate = DateTime.MinValue; //new DateTime(1, 1, 1); // Causes release date to be null d.Publish(d.User); - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); } catch(Exception ee) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs index 18b0e22a72..fd353d09cc 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/LiveEditing/Modules/CreateModule/CreateModule.cs @@ -132,7 +132,7 @@ namespace umbraco.presentation.LiveEditing.Modules.CreateModule DocumentType typeToCreate = new DocumentType(Convert.ToInt32(m_AllowedDocTypesDropdown.SelectedValue)); Document newDoc = Document.MakeNew(m_NameTextBox.Text, typeToCreate, new global::umbraco.BusinessLogic.User(userid), (int)UmbracoContext.Current.PageId); newDoc.Publish(new global::umbraco.BusinessLogic.User(userid)); - library.UpdateDocumentCache(newDoc.Id); + library.UpdateDocumentCache(newDoc); Page.Response.Redirect(library.NiceUrl(newDoc.Id), false); break; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs index 6a86e35fba..d2f8d32404 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/BaseContentTree.cs @@ -35,7 +35,7 @@ namespace umbraco.cms.presentation.Trees public BaseContentTree(string application) : base(application) { } - private User m_user; + private User _user; /// /// Returns the current User. This ensures that we don't instantiate a new User object @@ -45,7 +45,7 @@ namespace umbraco.cms.presentation.Trees { get { - return (m_user == null ? (m_user = UmbracoEnsuredPage.CurrentUser) : m_user); + return (_user == null ? (_user = UmbracoEnsuredPage.CurrentUser) : _user); } } @@ -113,7 +113,7 @@ function openContent(id) { node.OpenIcon = dd.ContentTypeIcon; } - if (dd.Published == false) + if (!dd.Published) node.Style.DimNode(); if (dd.HasPendingChanges()) diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs index 94c88425ac..d58e002785 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/actions/publish.aspx.cs @@ -39,7 +39,7 @@ namespace umbraco.presentation.actions confirm.Visible = false; d.Publish(getUser()); - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); deleted.Text = ui.Text("editContentPublishedHeader") + " ('" + d.Text + "') " + ui.Text("editContentPublishedText") + "

" + ui.Text("view") + " " + d.Text + ""; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs index afe99ac4d2..c1089d77be 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/channels/UmbracoMetaWeblogAPI.cs @@ -84,7 +84,7 @@ namespace umbraco.presentation.channels if (publish) { doc.Publish(new User(username)); - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } return true; } @@ -403,7 +403,7 @@ namespace umbraco.presentation.channels if (publish) { doc.Publish(new User(username)); - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } return doc.Id.ToString(); } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs index d8b99c6bba..bfe92ef3c6 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/publish.aspx.cs @@ -93,7 +93,7 @@ namespace umbraco.dialogs { if (doc.Published) { - library.UpdateDocumentCache(doc.Id); + library.UpdateDocumentCache(doc); } } @@ -117,7 +117,7 @@ namespace umbraco.dialogs { if (d.PublishWithResult(base.getUser())) { - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); feedbackMsg.type = umbraco.uicontrols.Feedback.feedbacktype.success; feedbackMsg.Text = ui.Text("publish", "nodePublish", d.Text, base.getUser()) + "

" + ui.Text("closeThisWindow") + ""; } @@ -142,7 +142,7 @@ namespace umbraco.dialogs { // Needed for supporting distributed calls if (UmbracoSettings.UseDistributedCalls) - library.UpdateDocumentCache(d.Id); + library.UpdateDocumentCache(d); else documents.Add(d); diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs index 7c7b17c3a2..de897b6209 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/DocumentExtensions.cs @@ -250,7 +250,7 @@ namespace umbraco } } - library.UpdateDocumentCache(document.Id); + library.UpdateDocumentCache(document); return document; } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs index e2ee304244..018e6d9ff5 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/users/UserPermissions.cs @@ -102,11 +102,11 @@ namespace umbraco.cms.presentation.user ///

/// Returns the current user permissions for the node specified /// - /// + /// /// - public List GetExistingNodePermission(int nodeID) + public List GetExistingNodePermission(int nodeId) { - string path = GetNodePath(nodeID); + var path = GetNodePath(nodeId); if (path != "") { //get the user and their permissions @@ -119,13 +119,13 @@ namespace umbraco.cms.presentation.user /// /// gets path attribute for node id passed /// - /// + /// /// - private string GetNodePath(int iNodeID) + private static string GetNodePath(int iNodeId) { - if (Document.IsDocument(iNodeID)) + if (Document.IsDocument(iNodeId)) { - Document doc = new Document(iNodeID); + var doc = new Document(iNodeId); return doc.Path; } @@ -135,14 +135,13 @@ namespace umbraco.cms.presentation.user /// /// Finds all child node IDs /// - /// - /// + /// /// - private List FindChildNodes(int nodeID) + private static IEnumerable FindChildNodes(int nodeId) { - Document[] docs = Document.GetChildrenForTree(nodeID); - List nodeIds = new List(); - foreach (Document doc in docs) + var docs = Document.GetChildrenForTree(nodeId); + var nodeIds = new List(); + foreach (var doc in docs) { nodeIds.Add(doc.Id); if (doc.HasChildren) @@ -153,16 +152,16 @@ namespace umbraco.cms.presentation.user return nodeIds; } - private void InsertPermissions(int[] nodeIDs, IAction permission) + private void InsertPermissions(IEnumerable nodeIDs, IAction permission) { foreach (int i in nodeIDs) InsertPermission(i, permission); } - private void InsertPermission(int nodeID, IAction permission) + private void InsertPermission(int nodeId, IAction permission) { //create a new CMSNode object but don't initialize (this prevents a db query) - CMSNode node = new CMSNode(nodeID, false); + var node = new CMSNode(nodeId, false); Permission.MakeNew(m_user, node, permission.Letter); } diff --git a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs index 16c51bae78..b88f7ac157 100644 --- a/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs +++ b/src/umbraco.datalayer/Utility/Installer/DefaultInstallerUtility.cs @@ -261,45 +261,5 @@ namespace umbraco.DataLayer.Utility.Installer #endregion } - /// - /// A triple (Field, Table, Version) meaning: - /// if a SELECT statement of Field FROM Table succeeds, - /// the database version is at least Version. - /// - /// - /// This also supports checking for a value in a table. - /// - public struct VersionSpecs - { - /// The SQL statament to execute in order to test for the specified version - public readonly string Sql; - - /// An integer identifying the expected row count from the Sql statement - public readonly int ExpectedRows; - - /// The minimum version number of a database that contains the specified field. - public readonly DatabaseVersion Version; - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The version. - public VersionSpecs(string sql, DatabaseVersion version) - : this(sql, -1, version) - { } - - /// - /// Initializes a new instance of the struct. - /// - /// The sql statement to execute. - /// The expected row count. - /// The version. - public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) - { - Sql = sql; - ExpectedRows = expectedRows; - Version = version; - } - } + } diff --git a/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs new file mode 100644 index 0000000000..c1237e1e97 --- /dev/null +++ b/src/umbraco.datalayer/Utility/Installer/VersionSpecs.cs @@ -0,0 +1,44 @@ +namespace umbraco.DataLayer.Utility.Installer +{ + /// + /// A triple (Field, Table, Version) meaning: + /// if a SELECT statement of Field FROM Table succeeds, + /// the database version is at least Version. + /// + /// + /// This also supports checking for a value in a table. + /// + public struct VersionSpecs + { + /// The SQL statament to execute in order to test for the specified version + public readonly string Sql; + + /// An integer identifying the expected row count from the Sql statement + public readonly int ExpectedRows; + + /// The minimum version number of a database that contains the specified field. + public readonly DatabaseVersion Version; + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The version. + public VersionSpecs(string sql, DatabaseVersion version) + : this(sql, -1, version) + { } + + /// + /// Initializes a new instance of the struct. + /// + /// The sql statement to execute. + /// The expected row count. + /// The version. + public VersionSpecs(string sql, int expectedRows, DatabaseVersion version) + { + Sql = sql; + ExpectedRows = expectedRows; + Version = version; + } + } +} \ No newline at end of file diff --git a/src/umbraco.datalayer/umbraco.datalayer.csproj b/src/umbraco.datalayer/umbraco.datalayer.csproj index c16bf518ae..9f91f604bd 100644 --- a/src/umbraco.datalayer/umbraco.datalayer.csproj +++ b/src/umbraco.datalayer/umbraco.datalayer.csproj @@ -124,6 +124,7 @@ + diff --git a/src/umbraco.webservices/documents/documentService.cs b/src/umbraco.webservices/documents/documentService.cs index 6292c02d6b..634033cffd 100644 --- a/src/umbraco.webservices/documents/documentService.cs +++ b/src/umbraco.webservices/documents/documentService.cs @@ -246,13 +246,13 @@ namespace umbraco.webservices.documents case documentCarrier.EPublishAction.Publish: if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } break; case documentCarrier.EPublishAction.Unpublish: if (doc.PublishWithResult(user)) { - umbraco.library.UnPublishSingleNode(doc.Id); + umbraco.library.UnPublishSingleNode(doc); } break; case documentCarrier.EPublishAction.Ignore: @@ -260,14 +260,14 @@ namespace umbraco.webservices.documents { if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } } else { if (doc.PublishWithResult(user)) { - umbraco.library.UpdateDocumentCache(doc.Id); + umbraco.library.UpdateDocumentCache(doc); } } break;