From b511ae3a1a51e86bdec55e6ca2a2cb76fc6a8013 Mon Sep 17 00:00:00 2001 From: Shannon Deminick Date: Thu, 30 Aug 2012 08:26:01 +0700 Subject: [PATCH] Created new LookupByIdQuery ILookup which is now the first thing that is looked up. Have cleaned up all of the default.aspx stuff so that no routing logic takes place there, all routing logic now takes place entirely in the module. --- .../DocumentLookups/LookupByAliasTests.cs | 2 +- .../DocumentLookups/LookupByIdTests.cs | 4 +- .../LookupByNiceUrlAndTemplateTests.cs | 6 +- .../RenderRouteHandlerTests.cs | 8 +- src/Umbraco.Web/Mvc/RenderRouteHandler.cs | 8 +- .../Routing/DefaultLastChanceLookup.cs | 14 +- src/Umbraco.Web/Routing/DocumentRequest.cs | 107 +++++----- src/Umbraco.Web/Routing/DocumentSearcher.cs | 111 ++++------ src/Umbraco.Web/Routing/IDocumentLookup.cs | 4 +- src/Umbraco.Web/Routing/LookupByAlias.cs | 9 +- .../{LookupById.cs => LookupByIdPath.cs} | 10 +- src/Umbraco.Web/Routing/LookupByNiceUrl.cs | 8 +- .../Routing/LookupByNiceUrlAndTemplate.cs | 2 +- .../Routing/LookupByPageIdQuery.cs | 30 +++ src/Umbraco.Web/Umbraco.Web.csproj | 3 +- src/Umbraco.Web/UmbracoModule.cs | 50 ++++- src/Umbraco.Web/WebBootManager.cs | 5 +- .../umbraco.presentation/default.aspx.cs | 190 ++++++------------ src/Umbraco.Web/umbraco.presentation/page.cs | 34 ++-- .../BasePages/BasePage.cs | 3 +- 20 files changed, 278 insertions(+), 330 deletions(-) rename src/Umbraco.Web/Routing/{LookupById.cs => LookupByIdPath.cs} (82%) create mode 100644 src/Umbraco.Web/Routing/LookupByPageIdQuery.cs 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