diff --git a/src/Umbraco.Web/Mvc/RenderMvcController.cs b/src/Umbraco.Web/Mvc/RenderMvcController.cs index ac65d28d3d..c5ce441bba 100644 --- a/src/Umbraco.Web/Mvc/RenderMvcController.cs +++ b/src/Umbraco.Web/Mvc/RenderMvcController.cs @@ -4,6 +4,7 @@ using System.Web.Mvc; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Services; +using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Routing; @@ -60,6 +61,14 @@ namespace Umbraco.Web.Mvc get { return ApplicationContext.DatabaseContext; } } + /// + /// Returns the Current published content item for rendering the content + /// + protected IPublishedContent CurrentPage + { + get { return PublishedContentRequest.PublishedContent; } + } + //TODO: make this protected once we make PublishedContentRequest not internal after we figure out what it should actually contain /// /// Returns the current PublishedContentRequest diff --git a/src/Umbraco.Web/Templates/TemplateRenderer.cs b/src/Umbraco.Web/Templates/TemplateRenderer.cs index ce2da96730..0967f0c360 100644 --- a/src/Umbraco.Web/Templates/TemplateRenderer.cs +++ b/src/Umbraco.Web/Templates/TemplateRenderer.cs @@ -1,5 +1,7 @@ using System; +using System.Globalization; using System.IO; +using System.Linq; using System.Web.Compilation; using System.Web.Mvc; using System.Web.Routing; @@ -8,6 +10,7 @@ using Umbraco.Web.Models; using Umbraco.Web.Mvc; using Umbraco.Web.Routing; using umbraco; +using umbraco.cms.businesslogic.language; namespace Umbraco.Web.Templates { @@ -61,8 +64,21 @@ namespace Umbraco.Web.Templates return; } - //set the culture to the same as is currently rendering - contentRequest.Culture = _umbracoContext.PublishedContentRequest.Culture; + //in some cases the UmbracoContext will not have a PublishedContentRequest assigned to it if we are not in the + //execution of a front-end rendered page. In this case set the culture to the default. + //set the culture to the same as is currently rendering + if (_umbracoContext.PublishedContentRequest == null) + { + var defaultLanguage = Language.GetAllAsList().FirstOrDefault(); + contentRequest.Culture = defaultLanguage == null + ? CultureInfo.CurrentUICulture + : new CultureInfo(defaultLanguage.CultureAlias); + } + else + { + contentRequest.Culture = _umbracoContext.PublishedContentRequest.Culture; + } + //set the doc that was found by id contentRequest.PublishedContent = doc; //set the template, either based on the AltTemplate found or the standard template of the doc diff --git a/src/umbraco.cms/businesslogic/CMSNode.cs b/src/umbraco.cms/businesslogic/CMSNode.cs index 4838cdc355..2b75d3e244 100644 --- a/src/umbraco.cms/businesslogic/CMSNode.cs +++ b/src/umbraco.cms/businesslogic/CMSNode.cs @@ -515,15 +515,17 @@ order by level,sortOrder"; SqlHelper.CreateParameter("@parentId", newParent.Id)); this.Parent = newParent; - this.sortOrder = maxSortOrder + 1; + this.sortOrder = maxSortOrder + 1; + } + + //detect if we have moved, then update the level and path + // issue: http://issues.umbraco.org/issue/U4-1579 + if (this.Path != newParent.Path + "," + this.Id.ToString()) + { this.Level = newParent.Level + 1; this.Path = newParent.Path + "," + this.Id.ToString(); } - //this.Parent = newParent; - //this.Level = newParent.Level + 1; - //this.Path = newParent.Path + "," + this.Id.ToString(); - //this code block should not be here but since the class structure is very poor and doesn't use //overrides (instead using shadows/new) for the Children property, when iterating over the children //and calling Move(), the super classes overridden OnMove or Move methods never get fired, so diff --git a/src/umbraco.cms/businesslogic/web/Document.cs b/src/umbraco.cms/businesslogic/web/Document.cs index 92f9defa4e..3517fd89c7 100644 --- a/src/umbraco.cms/businesslogic/web/Document.cs +++ b/src/umbraco.cms/businesslogic/web/Document.cs @@ -2,6 +2,7 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; +using System.Runtime.CompilerServices; using System.Xml; using Umbraco.Core; using Umbraco.Core.Models; @@ -150,7 +151,7 @@ namespace umbraco.cms.businesslogic.web umbracoNode.path, umbracoNode.sortOrder, coalesce(publishCheck.published,0) as isPublished, umbracoNode.createDate, cmsDocument.text, cmsDocument.updateDate, cmsContentVersion.versionDate, cmsDocument.releaseDate, cmsDocument.expireDate, cmsContentType.icon, cmsContentType.alias, cmsContentType.thumbnail, cmsContentType.description, cmsContentType.nodeId as contentTypeId, - umbracoNode.nodeUser + umbracoNode.nodeUser, umbracoNode.trashed from umbracoNode left join umbracoNode children on children.parentId = umbracoNode.id inner join cmsContent on cmsContent.nodeId = umbracoNode.id @@ -166,6 +167,7 @@ namespace umbraco.cms.businesslogic.web coalesce(publishCheck.published,0), umbracoNode.createDate, cmsDocument.text, cmsContentType.icon, cmsContentType.alias, cmsContentType.thumbnail, cmsContentType.description, cmsContentType.nodeId, cmsDocument.updateDate, cmsContentVersion.versionDate, cmsDocument.releaseDate, cmsDocument.expireDate, umbracoNode.nodeUser + umbracoNode.nodeUser, umbracoNode.trashed order by {1} "; @@ -382,6 +384,7 @@ namespace umbraco.cms.businesslogic.web return isDoc; } + /// /// Used to get the firstlevel/root documents of the hierachy /// @@ -850,7 +853,12 @@ namespace umbraco.cms.businesslogic.web /// /// The usercontext under which the action are performed /// True if the publishing succeed. Possible causes for not publishing is if an event aborts the publishing + /// [Obsolete("Obsolete, Use Umbraco.Core.Services.ContentService.Publish()", false)] + /// This method needs to be marked with [MethodImpl(MethodImplOptions.Synchronized)] + /// because we execute multiple queries affecting the same data, if two thread are to do this at the same time for the same node we may have problems + /// + [MethodImpl(MethodImplOptions.Synchronized)] public bool PublishWithResult(User u) { var e = new PublishEventArgs(); @@ -1416,24 +1424,21 @@ namespace umbraco.cms.businesslogic.web [Obsolete("Obsolete", false)] protected void PopulateDocumentFromReader(IRecordsReader dr) { - bool _hc = false; - - if (dr.GetInt("children") > 0) - _hc = true; + var hc = dr.GetInt("children") > 0; SetupDocumentForTree(dr.GetGuid("uniqueId") , dr.GetShort("level") , dr.GetInt("parentId") , dr.GetInt("nodeUser") , dr.GetInt("documentUser") - , (dr.GetInt("isPublished") == 1) + , !dr.GetBoolean("trashed") && (dr.GetInt("isPublished") == 1) //set published... double check trashed property , dr.GetString("path") , dr.GetString("text") , dr.GetDateTime("createDate") , dr.GetDateTime("updateDate") , dr.GetDateTime("versionDate") , dr.GetString("icon") - , _hc + , hc , dr.GetString("alias") , dr.GetString("thumbnail") , dr.GetString("description") diff --git a/src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.resx b/src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.resx index e3e9167bc1..0224ee5734 100644 --- a/src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.resx +++ b/src/umbraco.editorControls/MultiNodeTreePicker/MNTPResources.resx @@ -145,7 +145,7 @@ The XPath expression that is evaluated to match a start node can be evaluated at a global tree level, or matched from the current node being edited. - An xpath filter to match nodes that will be either enabled or disabled from being clicked (depending on what is selected for the XPath filter type). This XPath filter is for one node only so it should be formatted to select only one node. The XML to XPath against is the same as the Umbraco XML for one node.<br/><br/>Example: <code>/*[self::'myNodeType or self::yourNodeType]</code><br/><br/>The above would make all nodes of types: myNodeType or yourNodeType not selectable in the tree + An xpath filter to match nodes that will be either enabled or disabled from being clicked (depending on what is selected for the XPath filter type). This XPath filter is for one node only so it should be formatted to select only one node. The XML to XPath against is the same as the Umbraco XML for one node.<br/><br/>Example: <code>/*[self::myNodeType or self::yourNodeType]</code><br/><br/>The above would make all nodes of types: myNodeType or yourNodeType not selectable in the tree Should the XPath filter match nodes to enable nodes or disable nodes. If Enable is selected, this means that only nodes that match the XPath filter will be allowed to be selected in the tree picker and vise versa for Disabled