private static bool DetectCollision(ILogger logger, IContent content, string url, string culture, UmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, out UrlInfo urlInfo)
        {
            // test for collisions on the 'main' URL
            var uri = new Uri(url.TrimEnd(Constants.CharArrays.ForwardSlash), UriKind.RelativeOrAbsolute);

            if (uri.IsAbsoluteUri == false)
            {
                uri = uri.MakeAbsolute(umbracoContext.CleanedUmbracoUrl);
            }
            uri = UriUtility.UriToUmbraco(uri);
            var pcr = publishedRouter.CreateRequest(umbracoContext, uri);

            publishedRouter.TryRouteRequest(pcr);

            urlInfo = null;

            if (pcr.HasPublishedContent == false)
            {
                var logMsg = nameof(DetectCollision) + " did not resolve a content item for original url: {Url}, translated to {TranslatedUrl} and culture: {Culture}";
                if (pcr.IgnorePublishedContentCollisions)
                {
                    logger.Debug(typeof(UrlProviderExtensions), logMsg, url, uri, culture);
                }
                else
                {
                    logger.Warn(typeof(UrlProviderExtensions), logMsg, url, uri, culture);
                }

                urlInfo = UrlInfo.Message(textService.Localize("content", "routeErrorCannotRoute"), culture);
                return(true);
            }

            if (pcr.IgnorePublishedContentCollisions)
            {
                return(false);
            }

            if (pcr.PublishedContent.Id != content.Id)
            {
                var o = pcr.PublishedContent;
                var l = new List <string>();
                while (o != null)
                {
                    l.Add(o.Name());
                    o = o.Parent;
                }
                l.Reverse();
                var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")";

                urlInfo = UrlInfo.Message(textService.Localize("content", "routeError", new[] { s }), culture);
                return(true);
            }

            // no collision
            return(false);
        }
Example #2
0
        private static bool DetectCollision(IContent content, string url, string culture, UmbracoContext umbracoContext, IPublishedRouter publishedRouter, ILocalizedTextService textService, out UrlInfo urlInfo)
        {
            // test for collisions on the 'main' url
            var uri = new Uri(url.TrimEnd('/'), UriKind.RelativeOrAbsolute);

            if (uri.IsAbsoluteUri == false)
            {
                uri = uri.MakeAbsolute(umbracoContext.CleanedUmbracoUrl);
            }
            uri = UriUtility.UriToUmbraco(uri);
            var pcr = publishedRouter.CreateRequest(umbracoContext, uri);

            publishedRouter.TryRouteRequest(pcr);

            urlInfo = null;

            if (pcr.HasPublishedContent == false)
            {
                urlInfo = UrlInfo.Message(textService.Localize("content/routeErrorCannotRoute"), culture);
                return(true);
            }

            if (pcr.IgnorePublishedContentCollisions)
            {
                return(false);
            }

            if (pcr.PublishedContent.Id != content.Id)
            {
                var o = pcr.PublishedContent;
                var l = new List <string>();
                while (o != null)
                {
                    l.Add(o.Name());
                    o = o.Parent;
                }
                l.Reverse();
                var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent.Id + ")";

                urlInfo = UrlInfo.Message(textService.Localize("content/routeError", new[] { s }), culture);
                return(true);
            }

            // no collision
            return(false);
        }
Example #3
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ViewRenderer" /> class.
        /// </summary>
        /// <param name="publishedRouter">The published router.</param>
        /// <param name="umbracoContextAccessor">The umbraco context accessor.</param>
        public ViewRenderer(IPublishedRouter publishedRouter, IUmbracoContextAccessor umbracoContextAccessor)
        {
            var controller = new EmptyController();
            var wrapper    = new HttpContextWrapper(HttpContext.Current);
            var routeData  = new RouteData
            {
                Values = { { "controller", "empty" } },
            };

            this.context = controller.ControllerContext = new ControllerContext(wrapper, routeData, controller);
            var context = umbracoContextAccessor.UmbracoContext;

            if (context.PublishedRequest?.PublishedContent == null)
            {
                context.PublishedRequest = publishedRouter.CreateRequest(context);
                context.PublishedRequest.PublishedContent = context.Content.GetAtRoot().FirstOrDefault();
            }
        }
Example #4
0
        public void Render(int pageId, int?altTemplateId, StringWriter writer)
        {
            if (writer == null)
            {
                throw new ArgumentNullException(nameof(writer));
            }

            // instantiate a request and process
            // important to use CleanedUmbracoUrl - lowercase path-only version of the current url, though this isn't going to matter
            // terribly much for this implementation since we are just creating a doc content request to modify it's properties manually.
            var contentRequest = _publishedRouter.CreateRequest(_umbracoContextAccessor.UmbracoContext);

            var doc = contentRequest.UmbracoContext.ContentCache.GetById(pageId);

            if (doc == null)
            {
                writer.Write("<!-- Could not render template for Id {0}, the document was not found -->", pageId);
                return;
            }

            //in some cases the UmbracoContext will not have a PublishedRequest 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 (_umbracoContextAccessor.UmbracoContext.PublishedRequest == null)
            {
                var defaultLanguage = _languageService.GetAllLanguages().FirstOrDefault();
                contentRequest.Culture = defaultLanguage == null
                    ? CultureInfo.CurrentUICulture
                    : defaultLanguage.CultureInfo;
            }
            else
            {
                contentRequest.Culture = _umbracoContextAccessor.UmbracoContext.PublishedRequest.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
            var templateId = _webRoutingSection.DisableAlternativeTemplates || !altTemplateId.HasValue
                ? doc.TemplateId
                : altTemplateId.Value;

            if (templateId.HasValue)
            {
                contentRequest.TemplateModel = _fileService.GetTemplate(templateId.Value);
            }

            //if there is not template then exit
            if (contentRequest.HasTemplate == false)
            {
                if (altTemplateId.HasValue == false)
                {
                    writer.Write("<!-- Could not render template for Id {0}, the document's template was not found with id {0}-->", doc.TemplateId);
                }
                else
                {
                    writer.Write("<!-- Could not render template for Id {0}, the altTemplate was not found with id {0}-->", altTemplateId);
                }
                return;
            }

            //First, save all of the items locally that we know are used in the chain of execution, we'll need to restore these
            //after this page has rendered.
            SaveExistingItems(out var oldPublishedRequest, out var oldAltTemplate);

            try
            {
                //set the new items on context objects for this templates execution
                SetNewItemsOnContextObjects(contentRequest);

                //Render the template
                ExecuteTemplateRendering(writer, contentRequest);
            }
            finally
            {
                //restore items on context objects to continuing rendering the parent template
                RestoreItems(oldPublishedRequest, oldAltTemplate);
            }
        }
Example #5
0
        /// <summary>
        /// Processes the Umbraco Request
        /// </summary>
        /// <param name="httpContext"></param>
        /// <remarks>
        ///
        /// This will check if we are trying to route to the default back office page (i.e. ~/Umbraco/ or ~/Umbraco or ~/Umbraco/Default )
        /// and ensure that the MVC handler executes for that. This is required because the route for /Umbraco will never execute because
        /// files/folders exist there and we cannot set the RouteCollection.RouteExistingFiles = true since that will muck a lot of other things up.
        /// So we handle it here and explicitly execute the MVC controller.
        ///
        /// </remarks>
        void ProcessRequest(HttpContextBase httpContext)
        {
            // do not process if client-side request
            if (httpContext.Request.Url.IsClientSideRequest())
            {
                return;
            }

            if (Current.UmbracoContext == null)
            {
                throw new InvalidOperationException("The Current.UmbracoContext is null, ProcessRequest cannot proceed unless there is a current UmbracoContext");
            }

            var umbracoContext = Current.UmbracoContext;

            // re-write for the default back office path
            if (httpContext.Request.Url.IsDefaultBackOfficeRequest(_globalSettings))
            {
                if (EnsureRuntime(httpContext, umbracoContext.OriginalRequestUrl))
                {
                    RewriteToBackOfficeHandler(httpContext);
                }
                return;
            }

            // do not process if this request is not a front-end routable page
            var isRoutableAttempt = EnsureUmbracoRoutablePage(umbracoContext, httpContext);

            // raise event here
            UmbracoModule.OnRouteAttempt(this, new RoutableAttemptEventArgs(isRoutableAttempt.Result, umbracoContext, httpContext));
            if (isRoutableAttempt.Success == false)
            {
                return;
            }

            httpContext.Trace.Write("UmbracoModule", "Umbraco request confirmed");

            // ok, process

            // note: requestModule.UmbracoRewrite also did some stripping of &umbPage
            // from the querystring... that was in v3.x to fix some issues with pre-forms
            // auth. Paul Sterling confirmed in Jan. 2013 that we can get rid of it.

            // instantiate, prepare and process the published content request
            // important to use CleanedUmbracoUrl - lowercase path-only version of the current URL
            var request = _publishedRouter.CreateRequest(umbracoContext);

            umbracoContext.PublishedRequest = request;
            _publishedRouter.PrepareRequest(request);

            // HandleHttpResponseStatus returns a value indicating that the request should
            // not be processed any further, eg because it has been redirect. then, exit.
            if (UmbracoModule.HandleHttpResponseStatus(httpContext, request, _logger))
            {
                return;
            }

            if (request.HasPublishedContent == false)
            {
                httpContext.RemapHandler(new PublishedContentNotFoundHandler());
            }
            else
            {
                RewriteToUmbracoHandler(httpContext, request);
            }
        }