diff --git a/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs b/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs index fd331be25a..1f26a0c50f 100644 --- a/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs +++ b/src/Umbraco.Tests/DocumentLookups/LookupByAliasTests.cs @@ -27,7 +27,7 @@ namespace Umbraco.Tests.DocumentLookups var result = lookup.TrySetDocument(docRequest); Assert.IsTrue(result); - Assert.AreEqual(docRequest.NodeId, nodeMatch); + Assert.AreEqual(docRequest.DocumentId, nodeMatch); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/DocumentLookups/LookupByIdTests.cs b/src/Umbraco.Tests/DocumentLookups/LookupByIdTests.cs index 47a0332697..04d028ceb0 100644 --- a/src/Umbraco.Tests/DocumentLookups/LookupByIdTests.cs +++ b/src/Umbraco.Tests/DocumentLookups/LookupByIdTests.cs @@ -16,13 +16,13 @@ namespace Umbraco.Tests.DocumentLookups var routingContext = GetRoutingContext(urlAsString, template); var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url var docRequest = new DocumentRequest(url, routingContext); - var lookup = new LookupById(); + var lookup = new LookupByIdPath(); Umbraco.Core.Configuration.GlobalSettings.HttpContext = routingContext.UmbracoContext.HttpContext; var result = lookup.TrySetDocument(docRequest); Assert.IsTrue(result); - Assert.AreEqual(docRequest.NodeId, nodeMatch); + Assert.AreEqual(docRequest.DocumentId, nodeMatch); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlAndTemplateTests.cs b/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlAndTemplateTests.cs index 25d627c423..60bf7962ac 100644 --- a/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlAndTemplateTests.cs +++ b/src/Umbraco.Tests/DocumentLookups/LookupByNiceUrlAndTemplateTests.cs @@ -25,9 +25,9 @@ namespace Umbraco.Tests.DocumentLookups var result = lookup.TrySetDocument(docRequest); Assert.IsTrue(result); - Assert.IsNotNull(docRequest.Node); - Assert.IsNotNull(docRequest.TemplateLookup); - Assert.AreEqual("blah".ToUpperInvariant(), docRequest.TemplateLookup.TemplateAlias.ToUpperInvariant()); + Assert.IsNotNull(docRequest.Document); + Assert.IsNotNull(docRequest.Template); + Assert.AreEqual("blah".ToUpperInvariant(), docRequest.Template.Alias.ToUpperInvariant()); } } } \ No newline at end of file diff --git a/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs index 7dd31393f9..a1c2bf51cb 100644 --- a/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs +++ b/src/Umbraco.Tests/DocumentLookups/RenderRouteHandlerTests.cs @@ -43,8 +43,8 @@ namespace Umbraco.Tests.DocumentLookups var routingContext = GetRoutingContext("~/dummy-page", template, routeData); var docRequest = new DocumentRequest(routingContext.UmbracoContext.UmbracoUrl, routingContext) { - Node = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1174), - TemplateLookup = new TemplateLookup(template.Alias, template) + Document = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1174), + Template = template }; var handler = new RenderRouteHandler(new TestControllerFactory()); @@ -67,8 +67,8 @@ namespace Umbraco.Tests.DocumentLookups var routingContext = GetRoutingContext("~/dummy-page", template, routeData); var docRequest = new DocumentRequest(routingContext.UmbracoContext.UmbracoUrl, routingContext) { - Node = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1172), - TemplateLookup = new TemplateLookup(template.Alias, template) + Document = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1172), + Template = template }; var handler = new RenderRouteHandler(new TestControllerFactory()); diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs index ab637f4449..e6e22fe57a 100644 --- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs +++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs @@ -41,7 +41,7 @@ namespace Umbraco.Web.Mvc var renderModel = new RenderModel() { - CurrentDocument = docRequest.Node + CurrentDocument = docRequest.Document }; //put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine @@ -77,7 +77,7 @@ namespace Umbraco.Web.Mvc { //check if there's a custom controller assigned, base on the document type alias. - var controller = _controllerFactory.CreateController(requestContext, documentRequest.Node.DocumentTypeAlias); + var controller = _controllerFactory.CreateController(requestContext, documentRequest.Document.DocumentTypeAlias); //check if that controller exists @@ -93,14 +93,14 @@ namespace Umbraco.Web.Mvc } else { - LogHelper.Warn("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", documentRequest.Node.DocumentTypeAlias, controller.GetType().FullName, typeof(RenderMvcController).FullName); + LogHelper.Warn("The current Document Type {0} matches a locally declared controller of type {1}. Custom Controllers for Umbraco routing must inherit from '{2}'.", documentRequest.Document.DocumentTypeAlias, controller.GetType().FullName, typeof(RenderMvcController).FullName); //exit as we cannnot route to the custom controller, just route to the standard one. return def; } //check if the custom controller has an action with the same name as the template name (we convert ToUmbracoAlias since the template name might have invalid chars). //NOTE: This also means that all custom actions MUST be PascalCase.. but that should be standard. - var templateName = documentRequest.TemplateLookup.TemplateAlias.Split('.')[0].ToUmbracoAlias(StringAliasCaseType.PascalCase); + var templateName = documentRequest.Template.Alias.Split('.')[0].ToUmbracoAlias(StringAliasCaseType.PascalCase); def.ActionName = templateName; } diff --git a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs index 4664285a26..0b8d967530 100644 --- a/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs +++ b/src/Umbraco.Web/Routing/DefaultLastChanceLookup.cs @@ -24,7 +24,7 @@ namespace Umbraco.Web.Routing /// A value indicating whether an Umbraco document was found and assigned. public bool TrySetDocument(DocumentRequest docRequest) { - docRequest.Node = HandlePageNotFound(docRequest); + docRequest.Document = HandlePageNotFound(docRequest); return docRequest.HasNode; } @@ -79,17 +79,17 @@ namespace Umbraco.Web.Routing return currentPage; } - static List _customHandlerTypes = null; + static IEnumerable _customHandlerTypes = null; static readonly object CustomHandlerTypesLock = new object(); - void InitializeNotFoundHandlers() + IEnumerable InitializeNotFoundHandlers() { // initialize handlers // create the definition cache LogHelper.Debug("Registering custom handlers."); - _customHandlerTypes = new List(); + var customHandlerTypes = new List(); var customHandlers = new XmlDocument(); customHandlers.Load(Umbraco.Core.IO.IOHelper.MapPath(Umbraco.Core.IO.SystemFiles.NotFoundhandlersConfig)); @@ -127,8 +127,10 @@ namespace Umbraco.Web.Routing } if (type != null) - _customHandlerTypes.Add(type); + customHandlerTypes.Add(type); } + + return customHandlerTypes; } IEnumerable GetNotFoundHandlers() @@ -139,7 +141,7 @@ namespace Umbraco.Web.Routing lock (CustomHandlerTypesLock) { if (_customHandlerTypes == null) - InitializeNotFoundHandlers(); + _customHandlerTypes = InitializeNotFoundHandlers(); } var handlers = new List(); diff --git a/src/Umbraco.Web/Routing/DocumentRequest.cs b/src/Umbraco.Web/Routing/DocumentRequest.cs index c9d5f2dbc4..2e82e6b064 100644 --- a/src/Umbraco.Web/Routing/DocumentRequest.cs +++ b/src/Umbraco.Web/Routing/DocumentRequest.cs @@ -9,6 +9,7 @@ using System.Diagnostics; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using umbraco; using umbraco.BusinessLogic; using umbraco.NodeFactory; using umbraco.cms.businesslogic.web; @@ -19,60 +20,11 @@ using umbraco.interfaces; namespace Umbraco.Web.Routing { - /// - /// Represents a found template that is resolved by the ILookups. - /// The TemplateObject is the business logic object that represents a template, this will be different for - /// web forms and MVC. - /// - /// - /// NOTE: This is not the prettiest thing in the world and we cannot use generics but we need to avoid looking up - /// template objects more than once which would occur if we were only storing the alias. - /// Once we take templates out of the db this becomes even more interesting because the templateId on the XML - /// will probably not be an integer Id anymore but more like an alias so the reprecussions will be big. - /// - internal class TemplateLookup - { - /// - /// Static method to return an empty template lookup - /// - /// - internal static TemplateLookup NoTemplate() - { - return new TemplateLookup(); - } - - private TemplateLookup() - { - - } - - internal TemplateLookup(string alias, object templateObject) - { - TemplateAlias = alias; - TemplateObject = templateObject; - } - - internal bool FoundTemplate - { - get { return TemplateObject != null; } - } - - /// - /// The alias of the template found - /// - internal string TemplateAlias { get; private set; } - - /// - /// The business logic template object that has been found, null if not found - /// - internal object TemplateObject { get; private set; } - } - /// /// represents a request for one specified Umbraco document to be rendered /// by one specified template, using one particular culture. /// - internal class DocumentRequest + internal class DocumentRequest { public DocumentRequest(Uri uri, RoutingContext routingContext) { @@ -90,7 +42,7 @@ namespace Umbraco.Web.Routing /// XmlNode _xmlNode = null; - private IDocument _node = null; + private IDocument _document = null; #region Properties @@ -129,42 +81,73 @@ namespace Umbraco.Web.Routing /// public CultureInfo Culture { get; set; } - // TODO: fixme - do we want to have an ordered list of alternate cultures, + /// + /// Gets or sets a specific document version to render, by default this is null which means that + /// it will render the latest published version. + /// + internal Guid? DocumentVersion { get; set; } + + private page _umbracoPage; + + /// + /// Returns the Umbraco page object + /// + /// + /// This value is only + /// + internal page GetUmbracoPage() + { + if (_umbracoPage == null) + { + throw new InvalidOperationException("The umbraco page object is only available once Finalize()"); + } + return _umbracoPage; + } + + /// + /// Called when all lookups are completed and before the module passes the request off to a handler + /// + internal void CompleteRequest(page umbracoPage) + { + _umbracoPage = umbracoPage; + } + + // TODO: fixme - do we want to have an ordered list of alternate cultures, // to allow for fallbacks when doing dictionnary lookup and such? - public IDocument Node + public IDocument Document { - get { return _node; } + get { return _document; } set { - _node = value; - this.TemplateLookup = null; - _nodeId = _node != null ? _node.Id : 0; + _document = value; + this.Template = null; + _nodeId = _document != null ? _document.Id : 0; } } /// /// Gets or sets the document request's template lookup /// - public TemplateLookup TemplateLookup { get; set; } + public Template Template { get; set; } /// /// Gets a value indicating whether the document request has a template. /// public bool HasTemplate { - get { return this.TemplateLookup != null && TemplateLookup.FoundTemplate; } + get { return this.Template != null ; } } /// /// Gets the id of the document. /// /// Thrown when the document request has no document. - public int NodeId + public int DocumentId { get { - if (this.Node == null) + if (this.Document == null) throw new InvalidOperationException("DocumentRequest has no document."); return _nodeId; } @@ -175,7 +158,7 @@ namespace Umbraco.Web.Routing /// public bool HasNode { - get { return this.Node != null; } + get { return this.Document != null; } } /// diff --git a/src/Umbraco.Web/Routing/DocumentSearcher.cs b/src/Umbraco.Web/Routing/DocumentSearcher.cs index 99b8ec85ae..e8511b8813 100644 --- a/src/Umbraco.Web/Routing/DocumentSearcher.cs +++ b/src/Umbraco.Web/Routing/DocumentSearcher.cs @@ -162,7 +162,7 @@ namespace Umbraco.Web.Routing if (i == maxLoop || j == maxLoop) { LogHelper.Debug("{0}Looks like we're running into an infinite loop, abort", () => tracePrefix); - _documentRequest.Node = null; + _documentRequest.Document = null; } LogHelper.Debug("{0}End", () => tracePrefix); } @@ -176,11 +176,11 @@ namespace Umbraco.Web.Routing { const string tracePrefix = "FollowInternalRedirects: "; - if (_documentRequest.Node == null) + if (_documentRequest.Document == null) throw new InvalidOperationException("There is no node."); bool redirect = false; - string internalRedirect = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "umbracoInternalRedirectId"); + string internalRedirect = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Document, "umbracoInternalRedirectId"); if (!string.IsNullOrWhiteSpace(internalRedirect)) { @@ -193,10 +193,10 @@ namespace Umbraco.Web.Routing if (internalRedirectId <= 0) { // bad redirect - _documentRequest.Node = null; + _documentRequest.Document = null; LogHelper.Debug("{0}Failed to redirect to id={1}: invalid value", () => tracePrefix, () => internalRedirect); } - else if (internalRedirectId == _documentRequest.NodeId) + else if (internalRedirectId == _documentRequest.DocumentId) { // redirect to self LogHelper.Debug("{0}Redirecting to self, ignore", () => tracePrefix); @@ -208,7 +208,7 @@ namespace Umbraco.Web.Routing _umbracoContext, internalRedirectId); - _documentRequest.Node = node; + _documentRequest.Document = node; if (node != null) { redirect = true; @@ -232,12 +232,12 @@ namespace Umbraco.Web.Routing { const string tracePrefix = "EnsurePageAccess: "; - if (_documentRequest.Node == null) + if (_documentRequest.Document == null) throw new InvalidOperationException("There is no node."); - var path = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "@path"); + var path = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Document, "@path"); - if (Access.IsProtected(_documentRequest.NodeId, path)) + if (Access.IsProtected(_documentRequest.DocumentId, path)) { LogHelper.Debug("{0}Page is protected, check for access", () => tracePrefix); @@ -247,17 +247,17 @@ namespace Umbraco.Web.Routing { LogHelper.Debug("{0}Not logged in, redirect to login page", () => tracePrefix); var loginPageId = Access.GetLoginPage(path); - if (loginPageId != _documentRequest.NodeId) - _documentRequest.Node = _routingContext.PublishedContentStore.GetDocumentById( + if (loginPageId != _documentRequest.DocumentId) + _documentRequest.Document = _routingContext.PublishedContentStore.GetDocumentById( _umbracoContext, loginPageId); } - else if (!Access.HasAccces(_documentRequest.NodeId, user.ProviderUserKey)) + else if (!Access.HasAccces(_documentRequest.DocumentId, user.ProviderUserKey)) { LogHelper.Debug("{0}Current member has not access, redirect to error page", () => tracePrefix); var errorPageId = Access.GetErrorPage(path); - if (errorPageId != _documentRequest.NodeId) - _documentRequest.Node = _routingContext.PublishedContentStore.GetDocumentById( + if (errorPageId != _documentRequest.DocumentId) + _documentRequest.Document = _routingContext.PublishedContentStore.GetDocumentById( _umbracoContext, errorPageId); } @@ -277,67 +277,42 @@ namespace Umbraco.Web.Routing /// private void LookupTemplate() { + //return if the request already has a template assigned, this can be possible if an ILookup assigns one + if (_documentRequest.HasTemplate) return; + const string tracePrefix = "LookupTemplate: "; - if (_documentRequest.Node == null) + if (_documentRequest.Document == null) throw new InvalidOperationException("There is no node."); - var templateAlias = _umbracoContext.HttpContext.Request.QueryString["altTemplate"]; - if (string.IsNullOrWhiteSpace(templateAlias)) - templateAlias = _umbracoContext.HttpContext.Request.Form["altTemplate"]; + //gets item from query string, form, cookie or server vars + var templateAlias = _umbracoContext.HttpContext.Request["altTemplate"]; - // fixme - we might want to support cookies?!? NO but provide a hook to change the template - - if (!_documentRequest.HasTemplate || !string.IsNullOrWhiteSpace(templateAlias)) + if (templateAlias.IsNullOrWhiteSpace()) { - if (string.IsNullOrWhiteSpace(templateAlias)) - { - templateAlias = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "@TemplateId"); - LogHelper.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateAlias); - int templateId; - if (!int.TryParse(templateAlias, out templateId)) - templateId = 0; + //we don't have an alt template specified, so lookup the template id on the document and then lookup the template + // associated with it. + //TODO: When we remove the need for a database for templates, then this id should be irrelavent, not sure how were going to do this nicely. + + var templateIdAsString = _routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Document, "@TemplateId"); + LogHelper.Debug("{0}Look for template id={1}", () => tracePrefix, () => templateIdAsString); + int templateId; + if (!int.TryParse(templateIdAsString, out templateId)) + templateId = 0; - if (templateId > 0) - { - //TODO: Need to figure out if this is web forms or MVC based on template name somehow!! - var webFormsTemplate = new Template(templateId); - _documentRequest.TemplateLookup = new TemplateLookup(webFormsTemplate.Alias, webFormsTemplate); - } - else - { - _documentRequest.TemplateLookup = TemplateLookup.NoTemplate(); - } - } - else + if (templateId > 0) { - //TODO: Is this required??? I thought that was the purpose of the other LookupByNiceUrlAndTemplate? - LogHelper.Debug("{0}Look for template alias=\"{1}\" (altTemplate)", () => tracePrefix, () => templateAlias); - //TODO: Need to figure out if this is web forms or MVC based on template name somehow!! - var webFormsTemplate = Template.GetByAlias(templateAlias); - _documentRequest.TemplateLookup = webFormsTemplate != null - ? new TemplateLookup(webFormsTemplate.Alias, webFormsTemplate) - : TemplateLookup.NoTemplate(); - } - - if (!_documentRequest.HasTemplate) - { - LogHelper.Debug("{0}No template was found", () => tracePrefix); - - //TODO: I like the idea of this new setting, but lets get this in to the core at a later time, for now lets just get the basics working. - //if (Settings.HandleMissingTemplateAs404) - //{ - // this.Node = null; - // LogHelper.Debug("{0}Assume page not found (404)", tracePrefix); - //} - - // else we have no template - // and there isn't much more we can do about it - } - else - { - LogHelper.Debug("{0}Found", () => tracePrefix); - } + //NOTE: This will throw an exception if the template id doesn't exist, but that is ok to inform the front end. + var template = new Template(templateId); + _documentRequest.Template = template; + } + } + else + { + LogHelper.Debug("{0}Look for template alias=\"{1}\" (altTemplate)", () => tracePrefix, () => templateAlias); + //TODO: Need to figure out if this is web forms or MVC based on template name somehow!! + var template = Template.GetByAlias(templateAlias); + _documentRequest.Template = template; } } @@ -349,7 +324,7 @@ namespace Umbraco.Web.Routing if (_documentRequest.HasNode) { int redirectId; - if (!int.TryParse(_routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Node, "umbracoRedirect"), out redirectId)) + if (!int.TryParse(_routingContext.PublishedContentStore.GetDocumentProperty(_umbracoContext, _documentRequest.Document, "umbracoRedirect"), out redirectId)) redirectId = -1; string redirectUrl = "#"; if (redirectId > 0) diff --git a/src/Umbraco.Web/Routing/IDocumentLookup.cs b/src/Umbraco.Web/Routing/IDocumentLookup.cs index 17d74098ee..4ef2b7f872 100644 --- a/src/Umbraco.Web/Routing/IDocumentLookup.cs +++ b/src/Umbraco.Web/Routing/IDocumentLookup.cs @@ -1,5 +1,7 @@ namespace Umbraco.Web.Routing { + + /// /// Provides a method to try to find an assign an Umbraco document to a DocumentRequest. /// @@ -10,7 +12,7 @@ namespace Umbraco.Web.Routing /// /// The DocumentRequest. /// A value indicating whether an Umbraco document was found and assigned. - /// Optionally, can also assign the template, although that is not required. + /// Optionally, can also assign the template or anything else on the document request, although that is not required. bool TrySetDocument(DocumentRequest docRequest); } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/LookupByAlias.cs b/src/Umbraco.Web/Routing/LookupByAlias.cs index 115db65ab4..07b418498d 100644 --- a/src/Umbraco.Web/Routing/LookupByAlias.cs +++ b/src/Umbraco.Web/Routing/LookupByAlias.cs @@ -23,7 +23,7 @@ namespace Umbraco.Web.Routing /// A value indicating whether an Umbraco document was found and assigned. public bool TrySetDocument(DocumentRequest docRequest) { - //XmlNode node = null; + IDocument node = null; if (docRequest.Uri.AbsolutePath != "/") // no alias if "/" @@ -35,14 +35,11 @@ namespace Umbraco.Web.Routing if (node != null) { - docRequest.Node = node; - LogHelper.Debug("Path \"{0}\" is an alias for id={1}", () => docRequest.Uri.AbsolutePath, () => docRequest.NodeId); + docRequest.Document = node; + LogHelper.Debug("Path \"{0}\" is an alias for id={1}", () => docRequest.Uri.AbsolutePath, () => docRequest.DocumentId); } } - if (node == null) - LogHelper.Debug("Not an alias"); - return node != null; } } diff --git a/src/Umbraco.Web/Routing/LookupById.cs b/src/Umbraco.Web/Routing/LookupByIdPath.cs similarity index 82% rename from src/Umbraco.Web/Routing/LookupById.cs rename to src/Umbraco.Web/Routing/LookupByIdPath.cs index 8175757783..5ce5eaa715 100644 --- a/src/Umbraco.Web/Routing/LookupById.cs +++ b/src/Umbraco.Web/Routing/LookupByIdPath.cs @@ -14,7 +14,7 @@ namespace Umbraco.Web.Routing /// Handles /1234 where 1234 is the identified of a document. /// //[ResolutionWeight(20)] - internal class LookupById : IDocumentLookup + internal class LookupByIdPath : IDocumentLookup { /// /// Tries to find and assign an Umbraco document to a DocumentRequest. @@ -35,15 +35,15 @@ namespace Umbraco.Web.Routing if (nodeId > 0) { - LogHelper.Debug("Id={0}", () => nodeId); + LogHelper.Debug("Id={0}", () => nodeId); node = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( docRequest.RoutingContext.UmbracoContext, nodeId); if (node != null) { - docRequest.Node = node; - LogHelper.Debug("Found node with id={0}", () => docRequest.NodeId); + docRequest.Document = node; + LogHelper.Debug("Found node with id={0}", () => docRequest.DocumentId); } else { @@ -53,7 +53,7 @@ namespace Umbraco.Web.Routing } if (nodeId == -1) - LogHelper.Debug("Not a node id"); + LogHelper.Debug("Not a node id"); return node != null; } diff --git a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs index 2f3a24a136..c5ed09e770 100644 --- a/src/Umbraco.Web/Routing/LookupByNiceUrl.cs +++ b/src/Umbraco.Web/Routing/LookupByNiceUrl.cs @@ -57,7 +57,7 @@ namespace Umbraco.Web.Routing if (node != null) { - docreq.Node = node; + docreq.Document = node; LogHelper.Debug("Cache hit, id={0}", () => nodeId); } else @@ -75,12 +75,12 @@ namespace Umbraco.Web.Routing if (node != null) { - docreq.Node = node; - LogHelper.Debug("Query matches, id={0}", () => docreq.NodeId); + docreq.Document = node; + LogHelper.Debug("Query matches, id={0}", () => docreq.DocumentId); if (!docreq.RoutingContext.UmbracoContext.InPreviewMode) { - docreq.RoutingContext.UmbracoContext.RoutesCache.Store(docreq.NodeId, route); // will not write if previewing + docreq.RoutingContext.UmbracoContext.RoutesCache.Store(docreq.DocumentId, route); // will not write if previewing } } diff --git a/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs b/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs index 78d057f6a1..75e16ee94d 100644 --- a/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs +++ b/src/Umbraco.Web/Routing/LookupByNiceUrlAndTemplate.cs @@ -48,7 +48,7 @@ namespace Umbraco.Web.Routing node = LookupDocumentNode(docRequest, route); if (node != null) - docRequest.TemplateLookup = new TemplateLookup(template.Alias, template); + docRequest.Template = template; } else { diff --git a/src/Umbraco.Web/Routing/LookupByPageIdQuery.cs b/src/Umbraco.Web/Routing/LookupByPageIdQuery.cs new file mode 100644 index 0000000000..cf09dd1799 --- /dev/null +++ b/src/Umbraco.Web/Routing/LookupByPageIdQuery.cs @@ -0,0 +1,30 @@ +namespace Umbraco.Web.Routing +{ + /// + /// This looks up a document by checking for the umbPageId of a request/query string + /// + /// + /// This is used by library.RenderTemplate and also some of the macro rendering functionality like in + /// insertMacro.aspx and macroResultWrapper.aspx + /// + internal class LookupByPageIdQuery : IDocumentLookup + { + public bool TrySetDocument(DocumentRequest docRequest) + { + int pageId; + if (int.TryParse(docRequest.RoutingContext.UmbracoContext.HttpContext.Request["umbPageID"], out pageId)) + { + var doc = docRequest.RoutingContext.PublishedContentStore.GetDocumentById( + docRequest.RoutingContext.UmbracoContext, + pageId); + + if (doc != null) + { + docRequest.Document = doc; + return true; + } + } + return false; + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e481f134ec..a75bd1c647 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -244,6 +244,7 @@ + ASPXCodeBehind @@ -287,7 +288,7 @@ - + diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs index ebd7ef7670..255738f736 100644 --- a/src/Umbraco.Web/UmbracoModule.cs +++ b/src/Umbraco.Web/UmbracoModule.cs @@ -105,10 +105,7 @@ namespace Umbraco.Web //redirect if it has been flagged if (docreq.IsRedirect) httpContext.Response.Redirect(docreq.RedirectUrl, true); - - //TODO: Here I think we need to put the logic in to do what default.aspx is doing for the most part, - // especially assigning the pageID of the httpcontext so we can render macros in MVC - + //if no doc is found, send to our not found handler if (docreq.Is404) { @@ -118,17 +115,52 @@ namespace Umbraco.Web { if (!docreq.HasTemplate) { + LogHelper.Debug("No template was found"); + //TODO: If there is no template then we should figure out what to render, in v4 it is just a blank page but some think // that it should be a 404. IMO I think it should just be a blank page because it is still a content item in the //umbraco system, perhaps this should be put on the mail list? For now we will just make it a blank page + //TODO: I like the idea of this new setting, but lets get this in to the core at a later time, for now lets just get the basics working. + //if (Settings.HandleMissingTemplateAs404) + //{ + // this.Node = null; + // LogHelper.Debug("{0}Assume page not found (404)", tracePrefix); + //} httpContext.Response.Clear(); - httpContext.Response.End(); + httpContext.Response.End(); } + else + { + //ok everything is ready to pass off to our handlers (mvc or webforms) but we need to setup a few things + //mostly to do with legacy code,etc... - //TODO: Detect MVC vs WebForms - docreq.IsMvc = true; //TODO: This needs to be set in the ILookups based on the template - var isMvc = docreq.IsMvc; - RewriteToUmbracoHandler(HttpContext.Current, uri.Query, isMvc); + //check for a specific version to be rendered for the document + Guid requestVersion; + if (Guid.TryParse(httpContext.Request["umbVersion"], out requestVersion)) + { + // security check since it might not be a public version + var bp = new global::umbraco.BasePages.UmbracoEnsuredPage(); + bp.ensureContext(); + docreq.DocumentVersion = requestVersion; + } + + //we need to create an umbraco page object, again this is required for much of the legacy code to work + var umbracoPage = new page(docreq); + //we need to complete the request which assigns the page back to the docrequest to make it available for legacy handlers like default.aspx + docreq.CompleteRequest(umbracoPage); + + //this is required for many legacy things in umbraco to work + httpContext.Items["pageID"] = docreq.DocumentId; + //now we need to create the 'page' object, this is legacy again but is required by many things currently in umbraco to run + var page = new page(docreq); + //this is again required by many legacy objects + httpContext.Items.Add("pageElements", page.Elements); + + //TODO: Detect MVC vs WebForms + docreq.IsMvc = true; //TODO: This needs to be set in the ILookups based on the template + var isMvc = docreq.IsMvc; + RewriteToUmbracoHandler(HttpContext.Current, uri.Query, isMvc); + } } } } diff --git a/src/Umbraco.Web/WebBootManager.cs b/src/Umbraco.Web/WebBootManager.cs index d7327ee7ed..322ab952b4 100644 --- a/src/Umbraco.Web/WebBootManager.cs +++ b/src/Umbraco.Web/WebBootManager.cs @@ -27,7 +27,7 @@ namespace Umbraco.Web } public void Boot() - { + { InitializeResolvers(); } @@ -143,8 +143,9 @@ namespace Umbraco.Web //or in their own global.asax new[] { + typeof (LookupByPageIdQuery), typeof (LookupByNiceUrl), - typeof (LookupById), + typeof (LookupByIdPath), typeof (LookupByNiceUrlAndTemplate), typeof (LookupByProfile), typeof (LookupByAlias) diff --git a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs index 5808337f42..8971584368 100644 --- a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs +++ b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs @@ -43,131 +43,65 @@ namespace umbraco void Page_PreInit(Object sender, EventArgs e) { - //TODO: This still a bunch of routing stuff being handled here, this all needs to be handled in the HttpModule instead - - // get the document request + // get the document request and the page _docRequest = UmbracoContext.Current.DocumentRequest; - - // load request parameters - // any reason other than liveEditing why we want to do this?! - Guid requestVersion; - if (!Guid.TryParse(Request["umbVersion"], out requestVersion)) - requestVersion = Guid.Empty; - int requestId; - if (!int.TryParse(Request["umbPageID"], out requestId)) - requestId = -1; - - if (requestId <= 0) - { - // asking for a different version of the default document - if (requestVersion != Guid.Empty) - { - // security check - var bp = new BasePages.UmbracoEnsuredPage(); - bp.ensureContext(); - requestId = _docRequest.NodeId; - } - } - else - { - // asking for a specific document (and maybe a specific version) - // security check - var bp = new BasePages.UmbracoEnsuredPage(); - bp.ensureContext(); - } - - if (requestId <= 0) - { - // use the DocumentRequest if it has resolved - // else it means that no lookup could find a document to render - // or that the document to render has no template... - - //TODO: Will HasTemplate ever be false here?? - if (_docRequest.HasNode && _docRequest.HasTemplate) - { - _upage = new page(_docRequest); - UmbracoContext.Current.HttpContext.Items["pageID"] = _docRequest.NodeId; // legacy - fixme - var templatePath = SystemDirectories.Masterpages + "/" + _docRequest.TemplateLookup.TemplateAlias.Replace(" ", "") + ".master"; // fixme - should be in .Template! - this.MasterPageFile = templatePath; // set the template - } - else - { - //TODO: If there is no template but it has a node we shouldn't render a 404 I don't think - - // if we know we're 404, display the ugly message, else a blank page - if (_docRequest.Is404) - RenderNotFound(); - Response.End(); - return; - } - } - else - { - // override the document = ignore the DocumentRequest - // fixme - what if it fails? - var document = requestVersion == Guid.Empty ? new Document(requestId) : new Document(requestId, requestVersion); - _upage = new page(document); - UmbracoContext.Current.HttpContext.Items["pageID"] = requestId; // legacy - fixme - - // must fall back to old code - OnPreInitLegacy(); - } - - // reset the friendly path so it's used by forms, etc. - LogHelper.Debug(string.Format("Reset url to \"{0}\"", UmbracoContext.Current.RequestUrl)); + _upage = _docRequest.GetUmbracoPage(); + var templatePath = SystemDirectories.Masterpages + "/" + _docRequest.Template.Alias.Replace(" ", "") + ".master"; // fixme - should be in .Template! + this.MasterPageFile = templatePath; // set the template + + // reset the friendly path so it's used by forms, etc. Context.RewritePath(UmbracoContext.Current.RequestUrl.PathAndQuery); - - Context.Items.Add("pageElements", _upage.Elements); // legacy - fixme } - void OnPreInitLegacy() - { - if (_upage.Template == 0) - { - string custom404 = umbraco.library.GetCurrentNotFoundPageId(); - if (!String.IsNullOrEmpty(custom404)) - { - XmlNode xmlNodeNotFound = content.Instance.XmlContent.GetElementById(custom404); - if (xmlNodeNotFound != null) - { - _upage = new page(xmlNodeNotFound); - } - } - } + //SD: I'm nearly positive that this is taken care of in our DefaultLastChanceLookup class! - if (_upage.Template != 0) - { - this.MasterPageFile = template.GetMasterPageName(_upage.Template); + //void OnPreInitLegacy() + //{ + // if (_upage.Template == 0) + // { + // string custom404 = umbraco.library.GetCurrentNotFoundPageId(); + // if (!String.IsNullOrEmpty(custom404)) + // { + // XmlNode xmlNodeNotFound = content.Instance.XmlContent.GetElementById(custom404); + // if (xmlNodeNotFound != null) + // { + // _upage = new page(xmlNodeNotFound); + // } + // } + // } - //TODO: The culture stuff needs to all be set in the module + // if (_upage.Template != 0) + // { + // this.MasterPageFile = template.GetMasterPageName(_upage.Template); - string cultureAlias = null; - for (int i = _upage.SplitPath.Length - 1; i > 0; i--) - { - var domains = Domain.GetDomainsById(int.Parse(_upage.SplitPath[i])); - if (domains.Length > 0) - { - cultureAlias = domains[0].Language.CultureAlias; - break; - } - } + // string cultureAlias = null; + // for (int i = _upage.SplitPath.Length - 1; i > 0; i--) + // { + // var domains = Domain.GetDomainsById(int.Parse(_upage.SplitPath[i])); + // if (domains.Length > 0) + // { + // cultureAlias = domains[0].Language.CultureAlias; + // break; + // } + // } - if (cultureAlias != null) - { - LogHelper.Debug("Culture changed to " + cultureAlias, Context.Trace); - var culture = new System.Globalization.CultureInfo(cultureAlias); - Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = culture; - } - } - else - { - Response.StatusCode = 404; - RenderNotFound(); - Response.End(); - } - } + // if (cultureAlias != null) + // { + // LogHelper.Debug("Culture changed to " + cultureAlias, Context.Trace); + // var culture = new System.Globalization.CultureInfo(cultureAlias); + // Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = culture; + // } + // } + // else + // { + // Response.StatusCode = 404; + // RenderNotFound(); + // Response.End(); + // } + //} // + protected override void OnLoad(EventArgs e) { base.OnLoad(e); @@ -214,21 +148,21 @@ namespace umbraco writer.Write(text); } - //TODO: This should be removed, we should be handling all 404 stuff in the module and executing the - // DocumentNotFoundHttpHandler instead but we need to fix the above routing concerns so that this all - // takes place in the Module. - void RenderNotFound() - { - Context.Response.StatusCode = 404; + ////TODO: This should be removed, we should be handling all 404 stuff in the module and executing the + //// DocumentNotFoundHttpHandler instead but we need to fix the above routing concerns so that this all + //// takes place in the Module. + //void RenderNotFound() + //{ + // Context.Response.StatusCode = 404; - Response.Write("

Page not found

"); - UmbracoContext.Current.HttpContext.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(UmbracoContext.Current.ClientUrl) + "'.

"); + // Response.Write("

Page not found

"); + // UmbracoContext.Current.HttpContext.Response.Write("

No umbraco document matches the url '" + HttpUtility.HtmlEncode(UmbracoContext.Current.ClientUrl) + "'.

"); - // fixme - should try to get infos from the DocumentRequest? + // // fixme - should try to get infos from the DocumentRequest? - Response.Write("

This page can be replaced with a custom 404. Check the documentation for \"custom 404\".

"); - Response.Write("

This page is intentionally left ugly ;-)

"); - Response.Write(""); - } + // Response.Write("

This page can be replaced with a custom 404. Check the documentation for \"custom 404\".

"); + // Response.Write("

This page is intentionally left ugly ;-)

"); + // Response.Write(""); + //} } } diff --git a/src/Umbraco.Web/umbraco.presentation/page.cs b/src/Umbraco.Web/umbraco.presentation/page.cs index 55cec120d4..d7d3774784 100644 --- a/src/Umbraco.Web/umbraco.presentation/page.cs +++ b/src/Umbraco.Web/umbraco.presentation/page.cs @@ -92,33 +92,23 @@ namespace umbraco if (!docreq.HasNode) throw new ArgumentException("Document request has no node.", "docreq"); - - populatePageData(docreq.Node.Id, - docreq.Node.Name, docreq.Node.DocumentTypeId, docreq.Node.DocumentTypeAlias, - docreq.Node.WriterName, docreq.Node.CreatorName, docreq.Node.CreateDate, docreq.Node.UpdateDate, - docreq.Node.Path, docreq.Node.Version, docreq.Node.Parent == null ? -1 : docreq.Node.Parent.Id); + + //get the correct requested version + var docVersion = docreq.DocumentVersion.HasValue ? docreq.DocumentVersion.Value : docreq.Document.Version; + + populatePageData(docreq.Document.Id, + docreq.Document.Name, docreq.Document.DocumentTypeId, docreq.Document.DocumentTypeAlias, + docreq.Document.WriterName, docreq.Document.CreatorName, docreq.Document.CreateDate, docreq.Document.UpdateDate, + docreq.Document.Path, docVersion, docreq.Document.Parent == null ? -1 : docreq.Document.Parent.Id); if (docreq.HasTemplate) { - //TODO: The template property which returns just an int will be obsoleted once we remove the need for templates - // in the database but I suspect this will take a bit of work! - // Because the docrequest doesn't know about what template object we have (since the webforms template object is legacy) - // we need to check here to see if we can cast it. This should always work with webforms and the Template property of this - // object only gets used in very few places, the worrying part is that it is used in library.RenderMacroContent and library.RenderTemplate so not sure - // what would happen if someone tried to execute this inside of MVC... perhaps we can do a check in those methods and throw an exception if - // they are executed in MVC for now? - if (TypeHelper.IsTypeAssignableFrom