public override bool TryFindContent(PublishedRequest contentRequest)
        {
            string route;

            if (contentRequest.HasDomain)
            {
                route = contentRequest.Domain.ContentId.ToString() + DomainUtilities.PathRelativeToDomain(contentRequest.Domain.Uri, contentRequest.Uri.GetAbsolutePathDecoded());
            }
            else
            {
                route = contentRequest.Uri.GetAbsolutePathDecoded();
            }

            // This simple logic should do the trick: basically if I find an url with more than 4 segments (the 3 date parts and the slug)
            // I leave the last segment (the slug), remove the 3 date parts, and keep all the rest.
            var segmentLength = contentRequest.Uri.Segments.Length;

            if (segmentLength > 4)
            {
                var      stringDate = contentRequest.Uri.Segments[segmentLength - 4] + contentRequest.Uri.Segments[segmentLength - 3] + contentRequest.Uri.Segments[segmentLength - 2].TrimEnd("/");
                DateTime postDate;
                try
                {
                    postDate = DateTime.ParseExact(stringDate, "yyyy/MM/dd", CultureInfo.InvariantCulture);
                }
                catch (FormatException)
                {
                    return(false);
                }

                var newRoute = string.Empty;
                for (int i = 0; i < segmentLength; i++)
                {
                    if (i < segmentLength - 4 || i > segmentLength - 2)
                    {
                        newRoute += contentRequest.Uri.Segments[i];
                    }
                }
                var node = FindContent(contentRequest, newRoute);
                contentRequest.PublishedContent = null;
                // If by chance something matches the format pattern I check again if there is sucn a node and if it's an articulate post
                if (node == null || (node.ContentType.Alias != "ArticulateRichText" && node.ContentType.Alias != "ArticulateMarkdown"))
                {
                    return(false);
                }
                if (!node.Parent.Parent.Value <bool>("useDateFormatForUrl"))
                {
                    return(false);
                }
                if (node.Value <DateTime>("publishedDate").Date != postDate.Date)
                {
                    return(false);
                }

                contentRequest.PublishedContent = node;
                return(true);
            }

            return(false);
        }
    /// <summary>
    ///     Gets the culture assigned to a document by domains, in the context of a current Uri.
    /// </summary>
    /// <param name="content">The document.</param>
    /// <param name="umbracoContextAccessor"></param>
    /// <param name="siteDomainHelper"></param>
    /// <param name="current">An optional current Uri.</param>
    /// <returns>The culture assigned to the document by domains.</returns>
    /// <remarks>
    ///     <para>
    ///         In 1:1 multilingual setup, a document contains several cultures (there is not
    ///         one document per culture), and domains, withing the context of a current Uri, assign
    ///         a culture to that document.
    ///     </para>
    /// </remarks>
    public static string?GetCultureFromDomains(
        this IPublishedContent content,
        IUmbracoContextAccessor umbracoContextAccessor,
        ISiteDomainMapper siteDomainHelper,
        Uri?current = null)
    {
        IUmbracoContext umbracoContext = umbracoContextAccessor.GetRequiredUmbracoContext();

        return(DomainUtilities.GetCultureFromDomains(content.Id, content.Path, current, umbracoContext, siteDomainHelper));
    }
Esempio n. 3
0
    private async Task <IActionResult> GetMacroResultAsHtml(string?macroAlias, int pageId,
                                                            IDictionary <string, object>?macroParams)
    {
        IMacro?m = macroAlias is null ? null : _macroService.GetByAlias(macroAlias);

        if (m == null)
        {
            return(NotFound());
        }

        IUmbracoContext   umbracoContext   = _umbracoContextAccessor.GetRequiredUmbracoContext();
        IPublishedContent?publishedContent = umbracoContext.Content?.GetById(true, pageId);

        //if it isn't supposed to be rendered in the editor then return an empty string
        //currently we cannot render a macro if the page doesn't yet exist
        if (pageId == -1 || publishedContent == null || m.DontRender)
        {
            //need to create a specific content result formatted as HTML since this controller has been configured
            //with only json formatters.
            return(Content(string.Empty, "text/html", Encoding.UTF8));
        }


        // When rendering the macro in the backoffice the default setting would be to use the Culture of the logged in user.
        // Since a Macro might contain thing thats related to the culture of the "IPublishedContent" (ie Dictionary keys) we want
        // to set the current culture to the culture related to the content item. This is hacky but it works.

        // fixme
        // in a 1:1 situation we do not handle the language being edited
        // so the macro renders in the wrong language

        var culture = DomainUtilities.GetCultureFromDomains(publishedContent.Id, publishedContent.Path, null,
                                                            umbracoContext, _siteDomainHelper);

        if (culture != null)
        {
            Thread.CurrentThread.CurrentCulture       =
                Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture);
        }

        // must have an active variation context!
        _variationContextAccessor.VariationContext = new VariationContext(culture);

        using (umbracoContext.ForcedPreview(true))
        {
            //need to create a specific content result formatted as HTML since this controller has been configured
            //with only json formatters.
            return(Content(
                       (await _componentRenderer.RenderMacroForContent(publishedContent, m.Alias, macroParams)).ToString() ??
                       string.Empty, "text/html",
                       Encoding.UTF8));
        }
    }
        public ActionResult LogOn(LogOnModel model, string returnUrl)
        {
            if (ModelState.IsValid)
            {
                if (!Utilities.DevelopmentMode)
                {
                    var du = new DomainUtilities(Utilities.ResellerId, Utilities.Resellerpassword);
                    var result = du.LogIn(model.Email, model.Password, DomainUtilities.GetPublicIp());
                    if (result != string.Empty)
                    {
                        FormsService.SignIn(model.Email, model.RememberMe);
                        if (Url.IsLocalUrl(returnUrl))
                        {
                            return Redirect(returnUrl);
                        }
                        else
                        {
                            string selectedDomains;
                            try
                            {
                                selectedDomains = Session["domainnamearr"].ToString();
                            }
                            catch (Exception)
                            {
                                selectedDomains = string.Empty;
                            }
                            if(selectedDomains == string.Empty)
                                return RedirectToAction("Index", "Home");
                            else
                                return Redirect("/Domain/Domain");
                        }
                        /*else
                        {
                            ModelState.AddModelError("", "The user name or password provided is incorrect.");
                        } */
                    }
                    else
                    {
                        ModelState.AddModelError("Email", "The user name or password provided is incorrect.");
                    }
                }
                else
                {
                    FormsService.SignIn(model.Email, model.RememberMe);
                    return RedirectToAction("Index", "Home");
                }
            }

            // If we got this far, something failed, redisplay form
            return View(model);
        }
Esempio n. 5
0
    /// <summary>
    ///     Gets the other URLs of a published content.
    /// </summary>
    /// <param name="umbracoContextAccessor">The Umbraco context.</param>
    /// <param name="id">The published content id.</param>
    /// <param name="current">The current absolute URL.</param>
    /// <returns>The other URLs for the published content.</returns>
    /// <remarks>
    ///     <para>
    ///         Other URLs are those that <c>GetUrl</c> would not return in the current context, but would be valid
    ///         URLs for the node in other contexts (different domain for current request, umbracoUrlAlias...).
    ///     </para>
    /// </remarks>
    public virtual IEnumerable <UrlInfo> GetOtherUrls(int id, Uri current)
    {
        IUmbracoContext   umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
        IPublishedContent?node           = umbracoContext.Content?.GetById(id);

        if (node == null)
        {
            yield break;
        }

        // look for domains, walking up the tree
        IPublishedContent?         n          = node;
        IEnumerable <DomainAndUri>?domainUris =
            DomainUtilities.DomainsForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, n.Id, current, false);

        // n is null at root
        while (domainUris == null && n != null)
        {
            n          = n.Parent; // move to parent node
            domainUris = n == null
                ? null
                : DomainUtilities.DomainsForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, n.Id, current);
        }

        // no domains = exit
        if (domainUris == null)
        {
            yield break;
        }

        foreach (DomainAndUri d in domainUris)
        {
            var culture = d.Culture;

            // although we are passing in culture here, if any node in this path is invariant, it ignores the culture anyways so this is ok
            var route = umbracoContext.Content?.GetRouteById(id, culture);
            if (route == null)
            {
                continue;
            }

            // need to strip off the leading ID for the route if it exists (occurs if the route is for a node with a domain assigned)
            var pos  = route.IndexOf('/');
            var path = pos == 0 ? route : route.Substring(pos);

            var uri = new Uri(CombinePaths(d.Uri.GetLeftPart(UriPartial.Path), path));
            uri = _uriUtility.UriFromUmbraco(uri, _requestSettings);
            yield return(UrlInfo.Url(uri.ToString(), culture));
        }
    }
Esempio n. 6
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="DomainAndUri" /> class.
 /// </summary>
 /// <param name="domain">The original domain.</param>
 /// <param name="currentUri">The context current Uri.</param>
 public DomainAndUri(Domain domain, Uri currentUri)
     : base(domain)
 {
     try
     {
         Uri = DomainUtilities.ParseUriFromDomainName(Name, currentUri);
     }
     catch (UriFormatException)
     {
         throw new ArgumentException(
                   $"Failed to parse invalid domain: node id={domain.ContentId}, hostname=\"{Name.ToCSharpString()}\"."
                   + " Hostname should be a valid uri.",
                   nameof(domain));
     }
 }
Esempio n. 7
0
        private void AddToCacheIfDeepestRoute(IPublishedContent content, string route)
        {
            var domainRootNodeId = route.StartsWith("/") ? -1 : int.Parse(route.Substring(0, route.IndexOf('/')));

            // so we have a route that maps to a content... say "1234/path/to/content" - however, there could be a
            // domain set on "to" and route "4567/content" would also map to the same content - and due to how
            // urls computing work (by walking the tree up to the first domain we find) it is that second route
            // that would be returned - the "deepest" route - and that is the route we want to cache, *not* the
            // longer one - so make sure we don't cache the wrong route

            var deepest = DomainUtilities.ExistsDomainInPath(_domainCache.GetAll(false), content.Path, domainRootNodeId) == false;

            if (deepest)
            {
                _routesCache.Store(content.Id, route, true); // trusted route
            }
        }
Esempio n. 8
0
        /// <summary>
        /// Convert a DbCustomer into a domain Customer
        /// </summary>
        public static RopResult <Customer, DomainMessage> FromDbCustomer(DbCustomer sqlCustomer)
        {
            if (sqlCustomer == null)
            {
                return(Rop.Fail <Customer, DomainMessage>(DomainMessage.CustomerNotFound()));
            }

            var firstName  = DomainUtilities.CreateFirstName(sqlCustomer.FirstName);
            var lastName   = DomainUtilities.CreateLastName(sqlCustomer.LastName);
            var createName = Rop.Lift2 <String10, String10, PersonalName, DomainMessage>(PersonalName.Create);
            var name       = createName(firstName, lastName);

            var id         = DomainUtilities.CreateCustomerId(sqlCustomer.Id);
            var email      = DomainUtilities.CreateEmail(sqlCustomer.Email);
            var createCust = Rop.Lift3 <CustomerId, PersonalName, EmailAddress, Customer, DomainMessage>(Customer.Create);
            var cust       = createCust(id, name, email);

            return(cust);
        }
Esempio n. 9
0
    /// <summary>
    ///     Looks for wildcard domains in the path and updates <c>Culture</c> accordingly.
    /// </summary>
    internal void HandleWildcardDomains(IPublishedRequestBuilder request)
    {
        const string tracePrefix = "HandleWildcardDomains: ";

        if (request.PublishedContent == null)
        {
            return;
        }

        var nodePath = request.PublishedContent.Path;

        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("{TracePrefix}Path={NodePath}", tracePrefix, nodePath);
        }

        var             rootNodeId     = request.Domain != null ? request.Domain.ContentId : (int?)null;
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
        Domain?         domain         =
            DomainUtilities.FindWildcardDomainInPath(umbracoContext.PublishedSnapshot.Domains?.GetAll(true), nodePath, rootNodeId);

        // always has a contentId and a culture
        if (domain != null)
        {
            request.SetCulture(domain.Culture);
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    "{TracePrefix}Got domain on node {DomainContentId}, set culture to {CultureName}",
                    tracePrefix,
                    domain.ContentId,
                    request.Culture);
            }
        }
        else
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("{TracePrefix}No match.", tracePrefix);
            }
        }
    }
        /// <summary>
        /// Create a domain customer from a DTO or null if not valid.
        /// </summary>
        public static RopResult <Customer, DomainMessage> DtoToCustomer(CustomerDto dto)
        {
            if (dto == null)
            {
                // dto can be null if deserialization fails
                return(Rop.Fail <Customer, DomainMessage>(DomainMessage.CustomerIsRequired()));
            }

            var firstName  = DomainUtilities.CreateFirstName(dto.FirstName);
            var lastName   = DomainUtilities.CreateLastName(dto.LastName);
            var createName = Rop.Lift2 <String10, String10, PersonalName, DomainMessage>(PersonalName.Create);
            var name       = createName(firstName, lastName);

            var id         = DomainUtilities.CreateCustomerId(dto.Id);
            var email      = DomainUtilities.CreateEmail(dto.Email);
            var createCust = Rop.Lift3 <CustomerId, PersonalName, EmailAddress, Customer, DomainMessage>(Customer.Create);
            var cust       = createCust(id, name, email);

            return(cust);
        }
Esempio n. 11
0
    /// <summary>
    ///     Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
    /// </summary>
    /// <param name="frequest">The <c>PublishedRequest</c>.</param>
    /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
    public virtual Task <bool> TryFindContent(IPublishedRequestBuilder frequest)
    {
        if (!UmbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? _))
        {
            return(Task.FromResult(false));
        }

        string route;

        if (frequest.Domain != null)
        {
            route = frequest.Domain.ContentId +
                    DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.AbsolutePathDecoded);
        }
        else
        {
            route = frequest.AbsolutePathDecoded;
        }

        IPublishedContent?node = FindContent(frequest, route);

        return(Task.FromResult(node != null));
    }
    /// <summary>
    ///     Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
    /// </summary>
    /// <param name="frequest">The <c>PublishedRequest</c>.</param>
    /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
    /// <remarks>
    ///     Optionally, can also assign the template or anything else on the document request, although that is not
    ///     required.
    /// </remarks>
    public async Task <bool> TryFindContent(IPublishedRequestBuilder frequest)
    {
        if (!_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext))
        {
            return(false);
        }

        var route = frequest.Domain != null
            ? frequest.Domain.ContentId +
                    DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.AbsolutePathDecoded)
            : frequest.AbsolutePathDecoded;

        IRedirectUrl?redirectUrl = await _redirectUrlService.GetMostRecentRedirectUrlAsync(route, frequest.Culture);

        if (redirectUrl == null)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("No match for route: {Route}", route);
            }

            return(false);
        }

        IPublishedContent?content = umbracoContext.Content?.GetById(redirectUrl.ContentId);
        var url = content == null ? "#" : content.Url(_publishedUrlProvider, redirectUrl.Culture);

        if (url.StartsWith("#"))
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Route {Route} matches content {ContentId} which has no URL.", route, redirectUrl.ContentId);
            }

            return(false);
        }

        // Appending any querystring from the incoming request to the redirect URL
        url = string.IsNullOrEmpty(frequest.Uri.Query) ? url : url + frequest.Uri.Query;
        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Route {Route} matches content {ContentId} with URL '{Url}', redirecting.", route, content?.Id, url);
        }

        frequest
        .SetRedirectPermanent(url)

        // From: http://stackoverflow.com/a/22468386/5018
        // See http://issues.umbraco.org/issue/U4-8361#comment=67-30532
        // Setting automatic 301 redirects to not be cached because browsers cache these very aggressively which then leads
        // to problems if you rename a page back to it's original name or create a new page with the original name
        .SetNoCacheHeader(true)
        .SetCacheExtensions(new List <string> {
            "no-store, must-revalidate"
        })
        .SetHeaders(new Dictionary <string, string> {
            { "Pragma", "no-cache" }, { "Expires", "0" }
        });

        return(true);
    }
 public ActionResult Register(RegisterModel model)
 {
     if (ModelState.IsValid)
     {
         var du = new DomainUtilities(Utilities.ResellerId, Utilities.Resellerpassword);
         var result = du.SignUp(model.Email, model.Password, model.Name, model.Company, model.Address1,
                                model.Address2, model.City, model.State, model.Country, model.Zip, model.PhoneCc,
                                model.Mobile);
         if(!string.IsNullOrEmpty(result))
         {
             FormsService.SignIn(model.Email, true/* createPersistentCookie */);
             string selectedDomains;
             try
             {
                 selectedDomains = Session["domainnamearr"].ToString();
             }
             catch (Exception)
             {
                 selectedDomains = string.Empty;
             }
             if (selectedDomains == string.Empty)
                 return RedirectToAction("Index", "Home");
             return Redirect("/Domain/Domain");
         }
         ModelState.AddModelError("Custom", "Unable to process the registration, change username and try again.");
     }
     // If we got this far, something failed, redisplay form
     ViewModel.PasswordLength = 6;
     return View(model);
 }
    /// <summary>
    ///     Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
    /// </summary>
    /// <param name="frequest">The <c>PublishedRequest</c>.</param>
    /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
    /// <remarks>If successful, also assigns the template.</remarks>
    public override Task <bool> TryFindContent(IPublishedRequestBuilder frequest)
    {
        var path = frequest.AbsolutePathDecoded;

        if (frequest.Domain != null)
        {
            path = DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, path);
        }

        // no template if "/"
        if (path == "/")
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("No template in path '/'");
            }

            return(Task.FromResult(false));
        }

        // look for template in last position
        var pos           = path.LastIndexOf('/');
        var templateAlias = path.Substring(pos + 1);

        path = pos == 0 ? "/" : path.Substring(0, pos);;

        ITemplate?template = _fileService.GetTemplate(templateAlias);

        if (template == null)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Not a valid template: '{TemplateAlias}'", templateAlias);
            }

            return(Task.FromResult(false));
        }

        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Valid template: '{TemplateAlias}'", templateAlias);
        }

        // look for node corresponding to the rest of the route
        var route = frequest.Domain != null ? frequest.Domain.ContentId + path : path;
        IPublishedContent?node = FindContent(frequest, route);

        if (node == null)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Not a valid route to node: '{Route}'", route);
            }

            return(Task.FromResult(false));
        }

        // IsAllowedTemplate deals both with DisableAlternativeTemplates and ValidateAlternativeTemplates settings
        if (!node.IsAllowedTemplate(_contentTypeService, _webRoutingSettings, template.Id))
        {
            _logger.LogWarning(
                "Alternative template '{TemplateAlias}' is not allowed on node {NodeId}.", template.Alias, node.Id);
            frequest.SetPublishedContent(null); // clear
            return(Task.FromResult(false));
        }

        // got it
        frequest.SetTemplate(template);
        return(Task.FromResult(true));
    }
Esempio n. 15
0
 public ActionResult DomainChecking(string domainName, string domains)
 {
     var notavailablelist = new List<string>();
     var availablelist = new List<Domaindetails>();
     if (!Utilities.DevelopmentMode)
     {
         if (!string.IsNullOrEmpty(domainName) && !string.IsNullOrEmpty(domains))
         {
             var du = new DomainUtilities(Utilities.ResellerId, Utilities.Resellerpassword);
             var dms = domains.Split(',').ToList();
             string json = du.Checkdomainavailability(domainName, dms);
             if (!string.IsNullOrEmpty(json))
             {
                 var ser = new JavaScriptSerializer();
                 foreach (var domain in (Dictionary<String, object>)ser.Deserialize<Object>(json))
                 {
                     foreach (var details in (Dictionary<String, object>)domain.Value)
                     {
                         if (details.Value.ToString().ToLower() == "available")
                             availablelist.Add(new Domaindetails
                                                   {
                                                       Extension = domain.Key.Substring(domain.Key.IndexOf('.') + 1),
                                                       Name = domain.Key.Substring(0, domain.Key.IndexOf('.'))
                                                   });
                         else
                             notavailablelist.Add(domain.Key);
                         break;
                     }
                 }
             }
             ViewData["NotAvailableList"] = notavailablelist;
             ViewData["AvailableList"] = availablelist;
             return View();
         }
     }
     else
     {
         availablelist.Add(new Domaindetails { Extension = "com", Name = "santhoshinet" });
         availablelist.Add(new Domaindetails { Extension = "in", Name = "santhoshinet" });
         ViewData["NotAvailableList"] = notavailablelist;
         ViewData["AvailableList"] = availablelist;
         return View();
     }
     Response.Redirect("/index.htm");
     return null;
 }
Esempio n. 16
0
    /// <summary>
    ///     Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly.
    /// </summary>
    /// <returns>A value indicating whether a domain was found.</returns>
    internal bool FindDomain(IPublishedRequestBuilder request)
    {
        const string tracePrefix = "FindDomain: ";

        // note - we are not handling schemes nor ports here.
        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, request.Uri);
        }

        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
        IDomainCache?   domainsCache   = umbracoContext.PublishedSnapshot.Domains;
        var             domains        = domainsCache?.GetAll(false).ToList();

        // determines whether a domain corresponds to a published document, since some
        // domains may exist but on a document that has been unpublished - as a whole - or
        // that is not published for the domain's culture - in which case the domain does
        // not apply
        bool IsPublishedContentDomain(Domain domain)
        {
            // just get it from content cache - optimize there, not here
            IPublishedContent?domainDocument = umbracoContext.PublishedSnapshot.Content?.GetById(domain.ContentId);

            // not published - at all
            if (domainDocument == null)
            {
                return(false);
            }

            // invariant - always published
            if (!domainDocument.ContentType.VariesByCulture())
            {
                return(true);
            }

            // variant, ensure that the culture corresponding to the domain's language is published
            return(domain.Culture is not null && domainDocument.Cultures.ContainsKey(domain.Culture));
        }

        domains = domains?.Where(IsPublishedContentDomain).ToList();

        var defaultCulture = domainsCache?.DefaultCulture;

        // try to find a domain matching the current request
        DomainAndUri?domainAndUri = DomainUtilities.SelectDomain(domains, request.Uri, defaultCulture: defaultCulture);

        // handle domain - always has a contentId and a culture
        if (domainAndUri != null)
        {
            // matching an existing domain
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(
                    "{TracePrefix}Matches domain={Domain}, rootId={RootContentId}, culture={Culture}",
                    tracePrefix,
                    domainAndUri.Name,
                    domainAndUri.ContentId,
                    domainAndUri.Culture);
            }

            request.SetDomain(domainAndUri);

            // canonical? not implemented at the moment
            // if (...)
            // {
            //  _pcr.RedirectUrl = "...";
            //  return true;
            // }
        }
        else
        {
            // not matching any existing domain
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("{TracePrefix}Matches no domain", tracePrefix);
            }

            request.SetCulture(defaultCulture ?? CultureInfo.CurrentUICulture.Name);
        }

        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("{TracePrefix}Culture={CultureName}", tracePrefix, request.Culture);
        }

        return(request.Domain != null);
    }
Esempio n. 17
0
    /// <summary>
    ///     Tries to find and assign an Umbraco document to a <c>PublishedRequest</c>.
    /// </summary>
    /// <param name="frequest">The <c>PublishedRequest</c>.</param>
    /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
    public Task <bool> TryFindContent(IPublishedRequestBuilder frequest)
    {
        if (!_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext))
        {
            return(Task.FromResult(false));
        }

        if (_logger.IsEnabled(LogLevel.Debug))
        {
            _logger.LogDebug("Looking for a page to handle 404.");
        }

        int?domainContentId = null;

        // try to find a culture as best as we can
        var errorCulture = CultureInfo.CurrentUICulture.Name;

        if (frequest.Domain != null)
        {
            errorCulture    = frequest.Domain.Culture;
            domainContentId = frequest.Domain.ContentId;
        }
        else
        {
            var route = frequest.AbsolutePathDecoded;
            var pos   = route.LastIndexOf('/');
            IPublishedContent?node = null;
            while (pos > 1)
            {
                route = route.Substring(0, pos);
                node  = umbracoContext.Content?.GetByRoute(route, culture: frequest?.Culture);
                if (node != null)
                {
                    break;
                }

                pos = route.LastIndexOf('/');
            }

            if (node != null)
            {
                Domain?d = DomainUtilities.FindWildcardDomainInPath(
                    umbracoContext.PublishedSnapshot.Domains?.GetAll(true), node.Path, null);
                if (d != null)
                {
                    errorCulture = d.Culture;
                }
            }
        }

        var error404 = NotFoundHandlerHelper.GetCurrentNotFoundPageId(
            _contentSettings.Error404Collection.ToArray(),
            _entityService,
            new PublishedContentQuery(umbracoContext.PublishedSnapshot, _variationContextAccessor, _examineManager),
            errorCulture,
            domainContentId);

        IPublishedContent?content = null;

        if (error404.HasValue)
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Got id={ErrorNodeId}.", error404.Value);
            }

            content = umbracoContext.Content?.GetById(error404.Value);
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug(content == null
                    ? "Could not find content with that id."
                    : "Found corresponding content.");
            }
        }
        else
        {
            if (_logger.IsEnabled(LogLevel.Debug))
            {
                _logger.LogDebug("Got nothing.");
            }
        }

        frequest?
        .SetPublishedContent(content)
        .SetIs404();

        return(Task.FromResult(content != null));
    }
Esempio n. 18
0
    null;     // we have nothing to say

    #endregion

    #region GetOtherUrls

    /// <summary>
    ///     Gets the other URLs of a published content.
    /// </summary>
    /// <param name="id">The published content id.</param>
    /// <param name="current">The current absolute URL.</param>
    /// <returns>The other URLs for the published content.</returns>
    /// <remarks>
    ///     <para>
    ///         Other URLs are those that <c>GetUrl</c> would not return in the current context, but would be valid
    ///         URLs for the node in other contexts (different domain for current request, umbracoUrlAlias...).
    ///     </para>
    /// </remarks>
    public IEnumerable <UrlInfo> GetOtherUrls(int id, Uri current)
    {
        IUmbracoContext   umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
        IPublishedContent?node           = umbracoContext.Content?.GetById(id);

        if (node == null)
        {
            yield break;
        }

        if (!node.HasProperty(Constants.Conventions.Content.UrlAlias))
        {
            yield break;
        }

        // look for domains, walking up the tree
        IPublishedContent?         n          = node;
        IEnumerable <DomainAndUri>?domainUris = DomainUtilities.DomainsForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, n.Id, current, false);

        // n is null at root
        while (domainUris == null && n != null)
        {
            // move to parent node
            n          = n.Parent;
            domainUris = n == null
                ? null
                : DomainUtilities.DomainsForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, n.Id, current, false);
        }

        // determine whether the alias property varies
        var varies = node.GetProperty(Constants.Conventions.Content.UrlAlias) !.PropertyType.VariesByCulture();

        if (domainUris == null)
        {
            // no domain
            // if the property is invariant, then URL "/<alias>" is ok
            // if the property varies, then what are we supposed to do?
            //  the content finder may work, depending on the 'current' culture,
            //  but there's no way we can return something meaningful here
            if (varies)
            {
                yield break;
            }

            var umbracoUrlName = node.Value <string>(_publishedValueFallback, Constants.Conventions.Content.UrlAlias);
            var aliases        = umbracoUrlName?.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries);

            if (aliases == null || aliases.Any() == false)
            {
                yield break;
            }

            foreach (var alias in aliases.Distinct())
            {
                var path = "/" + alias;
                var uri  = new Uri(path, UriKind.Relative);
                yield return(UrlInfo.Url(_uriUtility.UriFromUmbraco(uri, _requestConfig).ToString()));
            }
        }
        else
        {
            // some domains: one URL per domain, which is "<domain>/<alias>"
            foreach (DomainAndUri domainUri in domainUris)
            {
                // if the property is invariant, get the invariant value, URL is "<domain>/<invariant-alias>"
                // if the property varies, get the variant value, URL is "<domain>/<variant-alias>"

                // but! only if the culture is published, else ignore
                if (varies && !node.HasCulture(domainUri.Culture))
                {
                    continue;
                }

                var umbracoUrlName = varies
                    ? node.Value <string>(_publishedValueFallback, Constants.Conventions.Content.UrlAlias, domainUri.Culture)
                    : node.Value <string>(_publishedValueFallback, Constants.Conventions.Content.UrlAlias);

                var aliases = umbracoUrlName?.Split(Constants.CharArrays.Comma, StringSplitOptions.RemoveEmptyEntries);

                if (aliases == null || aliases.Any() == false)
                {
                    continue;
                }

                foreach (var alias in aliases.Distinct())
                {
                    var path = "/" + alias;
                    var uri  = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path));
                    yield return(UrlInfo.Url(
                                     _uriUtility.UriFromUmbraco(uri, _requestConfig).ToString(),
                                     domainUri.Culture));
                }
            }
        }
    }