From c025dd463f1db3cf8ec1ab396ef0ab61488883c8 Mon Sep 17 00:00:00 2001 From: Shannon Date: Tue, 31 May 2016 17:24:40 +0200 Subject: [PATCH] Fixes up merging issues, bit of manual process with this one --- .../Migrations/Initial/BaseDataCreation.cs | 5 +- .../AddPreviewXmlTable.cs | 4 +- .../EnsureServersLockObject.cs | 57 ----------- src/Umbraco.Core/Services/IContentService.cs | 3 +- src/Umbraco.Core/Umbraco.Core.csproj | 1 - .../Migrations/MigrationIssuesTests.cs | 2 +- .../TestHelpers/BaseUmbracoApplicationTest.cs | 1 + .../Models/Mapping/ContentModelMapper.cs | 1 + .../PropertyEditors/GridPropertyEditor.cs | 1 + .../Routing/UrlProviderExtensions.cs | 2 +- .../umbraco.presentation/content.cs | 60 +++++++++--- .../umbraco/dialogs/sendToTranslation.aspx.cs | 98 +++++++++++++++++-- .../businesslogic/Packager/Installer.cs | 13 +-- 13 files changed, 148 insertions(+), 100 deletions(-) delete mode 100644 src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveZero/EnsureServersLockObject.cs diff --git a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs index ade245c587..dcf191e0dd 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Initial/BaseDataCreation.cs @@ -146,10 +146,7 @@ namespace Umbraco.Core.Persistence.Migrations.Initial //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1039, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1039", SortOrder = 2, UniqueId = new Guid("06f349a9-c949-4b6a-8660-59c10451af42"), Text = "Ultimate Picker", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1038, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1038", SortOrder = 2, UniqueId = new Guid("1251c96c-185c-4e9b-93f4-b48205573cbd"), Text = "Simple Editor", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); - - // all lock objects - _database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = Constants.System.ServersLock, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1," + Constants.System.ServersLock, SortOrder = 1, UniqueId = new Guid("0AF5E610-A310-4B6F-925F-E928D5416AF7"), Text = "LOCK: Servers", NodeObjectType = Constants.ObjectTypes.LockObjectGuid, CreateDate = DateTime.Now }); + //_database.Insert("umbracoNode", "id", false, new NodeDto { NodeId = 1042, Trashed = false, ParentId = -1, UserId = 0, Level = 1, Path = "-1,1042", SortOrder = 2, UniqueId = new Guid("0a452bd5-83f9-4bc3-8403-1286e13fb77e"), Text = "Macro Container", NodeObjectType = new Guid(Constants.ObjectTypes.DataType), CreateDate = DateTime.Now }); } private void CreateUmbracoLockData() diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs index 4e8d3165fb..4c5c18ea20 100644 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs +++ b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionFourOneZero/AddPreviewXmlTable.cs @@ -8,8 +8,8 @@ namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionFourOneZero [Migration("4.1.0", 0, GlobalSettings.UmbracoMigrationName)] public class AddPreviewXmlTable : MigrationBase { - public AddPreviewXmlTable(ISqlSyntaxProvider sqlSyntax, ILogger logger) - : base(sqlSyntax, logger) + public AddPreviewXmlTable(ILogger logger) + : base(logger) { } diff --git a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveZero/EnsureServersLockObject.cs b/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveZero/EnsureServersLockObject.cs deleted file mode 100644 index 6f9d74e5db..0000000000 --- a/src/Umbraco.Core/Persistence/Migrations/Upgrades/TargetVersionSevenFiveZero/EnsureServersLockObject.cs +++ /dev/null @@ -1,57 +0,0 @@ -using System; -using Umbraco.Core.Configuration; -using Umbraco.Core.Logging; -using Umbraco.Core.Models.Rdbms; -using Umbraco.Core.Persistence.SqlSyntax; - -namespace Umbraco.Core.Persistence.Migrations.Upgrades.TargetVersionSevenFiveZero -{ - // This migration exists for 7.3.0 but it seems like it was not always running properly - // if you're upgrading from 7.3.0 or higher than we add this migration, if you're upgrading - // from 7.3.0 or lower then you will already get this migration in the migration to get to 7.3.0 - [Migration("7.3.0", "7.5.0", 10, GlobalSettings.UmbracoMigrationName)] - public class EnsureServersLockObject : MigrationBase - { - public EnsureServersLockObject(ISqlSyntaxProvider sqlSyntax, ILogger logger) - : base(sqlSyntax, logger) - { } - - public override void Up() - { - // that lock object should have been part of BaseDataCreation since 7.3.0 but - // for some reason it was not, so it was created during migrations but not during - // new installs, so for ppl that upgrade, make sure they have it - - EnsureLockObject(Constants.System.ServersLock, "0AF5E610-A310-4B6F-925F-E928D5416AF7", "LOCK: Servers"); - } - - public override void Down() - { - // not implemented - } - - private void EnsureLockObject(int id, string uniqueId, string text) - { - var exists = Context.Database.Exists(id); - if (exists) return; - - Insert - .IntoTable("umbracoNode") - .EnableIdentityInsert() - .Row(new - { - id = id, // NodeId - trashed = false, - parentId = -1, - nodeUser = 0, - level = 1, - path = "-1," + id, - sortOrder = 0, - uniqueId = new Guid(uniqueId), - text = text, - nodeObjectType = new Guid(Constants.ObjectTypes.LockObject), - createDate = DateTime.Now - }); - } - } -} diff --git a/src/Umbraco.Core/Services/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index a5a3f35683..be6c57bea9 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -276,8 +276,7 @@ namespace Umbraco.Core.Services /// Field to order by /// Direction to order by /// Flag to indicate when ordering by system field - /// Search text filter - /// + /// /// An Enumerable list of objects IEnumerable GetPagedDescendants(int id, long pageIndex, int pageSize, out long totalRecords, string orderBy, Direction orderDirection, bool orderBySystemField, IQuery filter); diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 6accef758e..a5cf5797c4 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -469,7 +469,6 @@ - diff --git a/src/Umbraco.Tests/Migrations/MigrationIssuesTests.cs b/src/Umbraco.Tests/Migrations/MigrationIssuesTests.cs index 55d60eed66..6eaf530409 100644 --- a/src/Umbraco.Tests/Migrations/MigrationIssuesTests.cs +++ b/src/Umbraco.Tests/Migrations/MigrationIssuesTests.cs @@ -81,7 +81,7 @@ namespace Umbraco.Tests.Migrations }; DatabaseContext.Database.Insert(data); - var migration = new UpdateRelatedLinksData(SqlSyntax, Logger); + var migration = new UpdateRelatedLinksData(Logger); migration.UpdateRelatedLinksDataDo(DatabaseContext.Database); data = DatabaseContext.Database.Fetch("SELECT * FROM cmsPropertyData WHERE id=" + data.Id).FirstOrDefault(); diff --git a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs index c67f5d1c4b..90cf7afde6 100644 --- a/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs +++ b/src/Umbraco.Tests/TestHelpers/BaseUmbracoApplicationTest.cs @@ -212,6 +212,7 @@ namespace Umbraco.Tests.TestHelpers protected virtual ApplicationContext CreateApplicationContext() { + var evtMsgs = new TransientEventMessagesFactory(); var applicationContext = new ApplicationContext( //assign the db context new DatabaseContext(new DefaultDatabaseFactory( diff --git a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs index a824711035..b3e851a25e 100644 --- a/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/ContentModelMapper.cs @@ -15,6 +15,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Trees; using Umbraco.Web.Routing; using Umbraco.Core.PropertyEditors; +using Umbraco.Web._Legacy.Actions; namespace Umbraco.Web.Models.Mapping { diff --git a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs index 279a477135..3ace05d220 100644 --- a/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs +++ b/src/Umbraco.Web/PropertyEditors/GridPropertyEditor.cs @@ -13,6 +13,7 @@ using Umbraco.Core.Logging; using Umbraco.Core.Models; using Umbraco.Core.PropertyEditors; using Umbraco.Core.Services; +using Umbraco.Core.Xml; using UmbracoExamine; namespace Umbraco.Web.PropertyEditors diff --git a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs index 658cdb1413..09201776b0 100644 --- a/src/Umbraco.Web/Routing/UrlProviderExtensions.cs +++ b/src/Umbraco.Web/Routing/UrlProviderExtensions.cs @@ -72,7 +72,7 @@ namespace Umbraco.Web.Routing s = "/" + string.Join("/", l) + " (id=" + id + ")"; } - urls.Add(ui.Text("content", "routeError", s, umbracoContext.Security.CurrentUser)); + urls.Add(umbracoContext.Application.Services.TextService.Localize("content/routeError", s)); } else { diff --git a/src/Umbraco.Web/umbraco.presentation/content.cs b/src/Umbraco.Web/umbraco.presentation/content.cs index cf8499d1dc..6a648071c5 100644 --- a/src/Umbraco.Web/umbraco.presentation/content.cs +++ b/src/Umbraco.Web/umbraco.presentation/content.cs @@ -121,7 +121,6 @@ namespace umbraco private static readonly object DbReadSyncLock = new object(); private const string XmlContextContentItemKey = "UmbracoXmlContextContent"; - private const string XmlContextClonedContentItemKey = "UmbracoXmlContextContent.cloned"; private static string _umbracoXmlDiskCacheFileName = string.Empty; private volatile XmlDocument _xmlContent; @@ -215,6 +214,7 @@ namespace umbraco /// The parent node identifier. public void SortNodes(int parentId) { + var childNodesXPath = "./* [@id]"; using (var safeXml = GetSafeXmlWriter(false)) { var parentNode = parentId == -1 @@ -543,7 +543,6 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; get { return XmlFileEnabled && UmbracoConfig.For.UmbracoSettings().Content.XmlContentCheckForDiskChanges; } } - } #endregion @@ -747,7 +746,6 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; _releaser.Dispose(); _releaser = null; } - } private static string ChildNodesXPath @@ -813,7 +811,8 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; // save using (var fs = new FileStream(_xmlFileName, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize: 4096, useAsync: true)) { - SaveXmlToStream(xml, fs); + var bytes = Encoding.UTF8.GetBytes(SaveXmlToString(xml)); + fs.Write(bytes, 0, bytes.Length); } LogHelper.Info("Saved Xml to file."); @@ -827,7 +826,47 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; } } - private void SaveXmlToStream(XmlDocument xml, Stream writeStream) + // invoked by XmlCacheFilePersister ONLY and that one manages the MainDom, ie it + // will NOT try to save once the current app domain is not the main domain anymore + // (no need to test _released) + internal async Task SaveXmlToFileAsync() + { + LogHelper.Info("Save Xml to file..."); + + try + { + var xml = _xmlContent; // capture (atomic + volatile), immutable anyway + if (xml == null) return; + + // delete existing file, if any + DeleteXmlFile(); + + // ensure cache directory exists + var directoryName = Path.GetDirectoryName(_xmlFileName); + if (directoryName == null) + throw new Exception(string.Format("Invalid XmlFileName \"{0}\".", _xmlFileName)); + if (File.Exists(_xmlFileName) == false && Directory.Exists(directoryName) == false) + Directory.CreateDirectory(directoryName); + + // save + using (var fs = new FileStream(_xmlFileName, FileMode.Create, FileAccess.Write, FileShare.Read, bufferSize: 4096, useAsync: true)) + { + var bytes = Encoding.UTF8.GetBytes(SaveXmlToString(xml)); + await fs.WriteAsync(bytes, 0, bytes.Length); + } + + LogHelper.Info("Saved Xml to file."); + } + catch (Exception e) + { + // if something goes wrong remove the file + DeleteXmlFile(); + + LogHelper.Error("Failed to save Xml to file.", e); + } + } + + private string SaveXmlToString(XmlDocument xml) { // using that one method because we want to have proper indent // and in addition, writing async is never fully async because @@ -841,12 +880,8 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; // so ImportContent must also make sure of ignoring whitespaces! - if (writeStream.CanSeek) - { - writeStream.Position = 0; - } - - using (var xmlWriter = XmlWriter.Create(writeStream, new XmlWriterSettings + var sb = new StringBuilder(); + using (var xmlWriter = XmlWriter.Create(sb, new XmlWriterSettings { Indent = true, Encoding = Encoding.UTF8, @@ -856,6 +891,7 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; //xmlWriter.WriteProcessingInstruction("xml", "version=\"1.0\" encoding=\"utf-8\""); xml.WriteTo(xmlWriter); // already contains the xml declaration } + return sb.ToString(); } private XmlDocument LoadXmlFromFile() @@ -1113,6 +1149,8 @@ order by umbracoNode.level, umbracoNode.parentID, umbracoNode.sortOrder"; } + public class DocumentCacheEventArgs : System.ComponentModel.CancelEventArgs { } + public class RefreshContentEventArgs : System.ComponentModel.CancelEventArgs { } #endregion } diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs index f3a5cec362..0f46ff0e92 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/dialogs/sendToTranslation.aspx.cs @@ -98,26 +98,106 @@ namespace umbraco.presentation.dialogs int languageId; if (int.TryParse(language.SelectedValue, out languageId)) { - cms.businesslogic.translation.Translation.MakeNew( + // testing translate + MakeNew( _currentPage, - getUser(), - BusinessLogic.User.GetUser(int.Parse(translator.SelectedValue)), - new cms.businesslogic.language.Language(languageId), + Security.CurrentUser, + Services.UserService.GetUserById(int.Parse(translator.SelectedValue)), + new Language(int.Parse(language.SelectedValue)), comment.Text, includeSubpages.Checked, true); pane_form.Visible = false; pl_buttons.Visible = false; - feedback.Text = ui.Text("translation", "pageHasBeenSendToTranslation", _currentPage.Text, base.getUser()) + + feedback.Text = Services.TextService.Localize("translation/pageHasBeenSendToTranslation", _currentPage.Text) + "

" + - ui.Text("defaultdialogs", "closeThisWindow") + "

"; - feedback.type = uicontrols.Feedback.feedbacktype.success; + Services.TextService.Localize("defaultdialogs/closeThisWindow") + "

"; + feedback.type = Feedback.feedbacktype.success; } else { - feedback.Text = ui.Text("translation", "noLanguageSelected"); - feedback.type = uicontrols.Feedback.feedbacktype.error; + feedback.Text = Services.TextService.Localize("translation/noLanguageSelected"); + feedback.type = Feedback.feedbacktype.error; + } + } + + public void MakeNew(CMSNode Node, IUser User, IUser Translator, Language Language, string Comment, + bool IncludeSubpages, bool SendEmail) + { + // Get translation taskType for obsolete task constructor + var taskType = Services.TaskService.GetTaskTypeByAlias("toTranslate"); + + // Create pending task + var t = new cms.businesslogic.task.Task(new Task(taskType)); + t.Comment = Comment; + t.Node = Node; + t.ParentUser = User; + t.User = Translator; + t.Save(); + + Services.AuditService.Add(AuditType.SendToTranslate, + "Translator: " + Translator.Name + ", Language: " + Language.FriendlyName, + User.Id, Node.Id); + + // send it + if (SendEmail) + { + string serverName = HttpContext.Current.Request.ServerVariables["SERVER_NAME"]; + int port = HttpContext.Current.Request.Url.Port; + + if (port != 80) + serverName += ":" + port; + + serverName += IOHelper.ResolveUrl(SystemDirectories.Umbraco); + + // Send mail + string[] subjectVars = { serverName, Node.Text }; + string[] bodyVars = { + Translator.Name, Node.Text, User.Name, + serverName, t.Id.ToString(), + Language.FriendlyName + }; + + if (User.Email != "" && User.Email.Contains("@") && Translator.Email != "" && + Translator.Email.Contains("@")) + { + // create the mail message + using (MailMessage mail = new MailMessage(User.Email, Translator.Email)) + { + // populate the message + mail.Subject = Services.TextService.Localize("translation/mailSubject", Translator.GetUserCulture(Services.TextService), subjectVars); + mail.IsBodyHtml = false; + mail.Body = Services.TextService.Localize("translation/mailBody", Translator.GetUserCulture(Services.TextService), bodyVars); + try + { + using (SmtpClient sender = new SmtpClient()) + { + sender.Send(mail); + } + } + catch (Exception ex) + { + LogHelper.Error("Error sending translation e-mail", ex); + } + } + + } + else + { + LogHelper.Warn("Could not send translation e-mail because either user or translator lacks e-mail in settings"); + } + + } + + if (IncludeSubpages) + { + //store children array here because iterating over an Array property object is very inneficient. + var c = Node.Children; + foreach (CMSNode n in c) + { + MakeNew(n, User, Translator, Language, Comment, true, false); + } } } } diff --git a/src/umbraco.cms/businesslogic/Packager/Installer.cs b/src/umbraco.cms/businesslogic/Packager/Installer.cs index 777a1eb062..7de1435e90 100644 --- a/src/umbraco.cms/businesslogic/Packager/Installer.cs +++ b/src/umbraco.cms/businesslogic/Packager/Installer.cs @@ -299,18 +299,7 @@ namespace umbraco.cms.businesslogic.packager // Get current user, with a fallback var currentUser = ApplicationContext.Current.Services.UserService.GetUserById(0); - //if there's a context, try to resolve the user - this will return null if there is a context but no - // user found when there are old/invalid cookies lying around most likely during installation. - // in that case we'll keep using the admin user - if (string.IsNullOrEmpty(BasePages.UmbracoEnsuredPage.umbracoUserContextID) == false) - { - if (BasePages.UmbracoEnsuredPage.ValidateUserContextID(BasePages.UmbracoEnsuredPage.umbracoUserContextID)) - { - var userById = //User.GetCurrent(); - if (userById != null) - currentUser = userById; - } - } + //TODO: Get rid of this entire class! Until then all packages will be installed by the admin user //Xml as XElement which is used with the new PackagingService