Example #1
0
 /// <summary>
 ///     Generates a URL based on the current Umbraco URL with a custom query string that will route to the specified
 ///     SurfaceController
 /// </summary>
 /// <returns></returns>
 public static string SurfaceAction(
     this IUrlHelper url,
     IUmbracoContext umbracoContext,
     IDataProtectionProvider dataProtectionProvider,
     string action,
     string controllerName) =>
 url.SurfaceAction(umbracoContext, dataProtectionProvider, action, controllerName, null);
        /// <summary>
        /// Outputs and caches a partial view in MVC
        /// </summary>
        /// <param name="appCaches"></param>
        /// <param name="hostingEnvironment"></param>
        /// <param name="umbracoContext"></param>
        /// <param name="htmlHelper"></param>
        /// <param name="partialViewName"></param>
        /// <param name="model"></param>
        /// <param name="cacheTimeout"></param>
        /// <param name="cacheKey">used to cache the partial view, this key could change if it is cached by page or by member</param>
        /// <param name="viewData"></param>
        /// <returns></returns>
        public static IHtmlContent CachedPartialView(
            this AppCaches appCaches,
            IHostingEnvironment hostingEnvironment,
            IUmbracoContext umbracoContext,
            IHtmlHelper htmlHelper,
            string partialViewName,
            object model,
            TimeSpan cacheTimeout,
            string cacheKey,
            ViewDataDictionary viewData = null
            )
        {
            //disable cached partials in debug mode: http://issues.umbraco.org/issue/U4-5940
            //disable cached partials in preview mode: https://github.com/umbraco/Umbraco-CMS/issues/10384
            if (hostingEnvironment.IsDebugMode || (umbracoContext?.InPreviewMode == true))
            {
                // just return a normal partial view instead
                return(htmlHelper.Partial(partialViewName, model, viewData));
            }

            var result = appCaches.RuntimeCache.GetCacheItem <IHtmlContent>(
                CoreCacheHelperExtensions.PartialViewCacheKey + cacheKey,
                () => new HtmlString(htmlHelper.Partial(partialViewName, model, viewData).ToHtmlString()),
                timeout: cacheTimeout);

            return(result);
        }
Example #3
0
        /// <summary>
        /// Gets the URL of a published content.
        /// </summary>
        /// <param name="content">The published content.</param>
        /// <param name="mode">The URL mode.</param>
        /// <param name="culture">A culture.</param>
        /// <param name="current">The current absolute URL.</param>
        /// <returns>The URL for the published content.</returns>
        /// <remarks>
        /// <para>The URL is absolute or relative depending on <c>mode</c> and on <c>current</c>.</para>
        /// <para>If the published content is multi-lingual, gets the URL for the specified culture or,
        /// when no culture is specified, the current culture.</para>
        /// <para>If the provider is unable to provide a URL, it returns "#".</para>
        /// </remarks>
        public string GetUrl(IPublishedContent?content, UrlMode mode = UrlMode.Default, string?culture = null, Uri?current = null)
        {
            if (content == null || content.ContentType.ItemType == PublishedItemType.Element)
            {
                return("#");
            }

            if (mode == UrlMode.Default)
            {
                mode = Mode;
            }

            // this the ONLY place where we deal with default culture - IUrlProvider always receive a culture
            // be nice with tests, assume things can be null, ultimately fall back to invariant
            // (but only for variant content of course)
            // We need to check all ancestors because urls are variant even for invariant content, if an ancestor is variant.
            if (culture == null && content.AncestorsOrSelf().Any(x => x.ContentType.VariesByCulture()))
            {
                culture = _variationContextAccessor?.VariationContext?.Culture ?? string.Empty;
            }

            if (current == null)
            {
                IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
                current = umbracoContext.CleanedUmbracoUrl;
            }


            UrlInfo?url = _urlProviders.Select(provider => provider.GetUrl(content, mode, culture, current))
                          .FirstOrDefault(u => u is not null);

            return(url?.Text ?? "#"); // legacy wants this
        }
Example #4
0
        /// <summary>
        /// Generates a URL based on the current Umbraco URL with a custom query string that will route to the specified SurfaceController
        /// </summary>
        /// <param name="url"></param>
        /// <param name="action"></param>
        /// <param name="controllerName"></param>
        /// <param name="area"></param>
        /// <param name="additionalRouteVals"></param>
        /// <returns></returns>
        public static string SurfaceAction(this IUrlHelper url, IUmbracoContext umbracoContext, IDataProtectionProvider dataProtectionProvider, string action, string controllerName, string area, object?additionalRouteVals)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }
            if (string.IsNullOrEmpty(action))
            {
                throw new ArgumentException("Value can't be empty.", nameof(action));
            }
            if (controllerName == null)
            {
                throw new ArgumentNullException(nameof(controllerName));
            }
            if (string.IsNullOrEmpty(controllerName))
            {
                throw new ArgumentException("Value can't be empty.", nameof(controllerName));
            }

            var encryptedRoute = EncryptionHelper.CreateEncryptedRouteString(dataProtectionProvider, controllerName, action, area, additionalRouteVals);

            var result = umbracoContext.OriginalRequestUrl.AbsolutePath.EnsureEndsWith('?') + "ufprt=" + encryptedRoute;

            return(result);
        }
Example #5
0
 public PageService(
     IProfileLogger profileLogger,
     IUmbracoContext umbracoContext)
 {
     _profileLogger  = profileLogger;
     _umbracoContext = umbracoContext;
 }
Example #6
0
        internal UrlInfo GetUrlFromRoute(
            string route,
            IUmbracoContext umbracoContext,
            int id,
            Uri current,
            UrlMode mode,
            string culture)
        {
            if (string.IsNullOrWhiteSpace(route))
            {
                _logger.LogDebug(
                    "Couldn't find any page with nodeId={NodeId}. This is most likely caused by the page not being published.",
                    id);
                return(null);
            }

            // extract domainUri and path
            // route is /<path> or <domainRootId>/<path>
            var          pos       = route.IndexOf('/');
            var          path      = pos == 0 ? route : route.Substring(pos);
            DomainAndUri domainUri = pos == 0
                ? null
                : DomainUtilities.DomainForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, int.Parse(route.Substring(0, pos), CultureInfo.InvariantCulture), current, culture);

            var defaultCulture = _localizationService.GetDefaultLanguageIsoCode();

            if (domainUri is not null || string.IsNullOrEmpty(culture) || culture.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase))
            {
                var url = AssembleUrl(domainUri, path, current, mode).ToString();
                return(UrlInfo.Url(url, culture));
            }

            return(null);
        }
    private bool _readonly; // after prepared

    /// <summary>
    ///     Initializes a new instance of the <see cref="PublishedRequest" /> class.
    /// </summary>
    public PublishedRequestOld(IPublishedRouter publishedRouter, IUmbracoContext umbracoContext, IOptions <WebRoutingSettings> webRoutingSettings, Uri?uri = null)
    {
        UmbracoContext      = umbracoContext ?? throw new ArgumentNullException(nameof(umbracoContext));
        _publishedRouter    = publishedRouter ?? throw new ArgumentNullException(nameof(publishedRouter));
        _webRoutingSettings = webRoutingSettings.Value;
        Uri = uri ?? umbracoContext.CleanedUmbracoUrl;
    }
        /// <summary>
        /// Initializes a new instance of the <see cref="UmbracoContextReference"/> class.
        /// </summary>
        public UmbracoContextReference(IUmbracoContext umbracoContext, bool isRoot, IUmbracoContextAccessor umbracoContextAccessor)
        {
            IsRoot = isRoot;

            UmbracoContext          = umbracoContext;
            _umbracoContextAccessor = umbracoContextAccessor;
        }
    private static async Task <Attempt <UrlInfo?> > DetectCollisionAsync(
        ILogger logger,
        IContent content,
        string url,
        string culture,
        IUmbracoContext umbracoContext,
        IPublishedRouter publishedRouter,
        ILocalizedTextService textService,
        IVariationContextAccessor variationContextAccessor,
        UriUtility uriUtility)
    {
        // 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);
        IPublishedRequestBuilder builder = await publishedRouter.CreateRequestAsync(uri);

        IPublishedRequest pcr =
            await publishedRouter.RouteRequestAsync(builder, new RouteRequestOptions(RouteDirection.Outbound));

        if (!pcr.HasPublishedContent())
        {
            const string logMsg = nameof(DetectCollisionAsync) +
                                  " did not resolve a content item for original url: {Url}, translated to {TranslatedUrl} and culture: {Culture}";
            logger.LogDebug(logMsg, url, uri, culture);

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

        if (pcr.IgnorePublishedContentCollisions)
        {
            return(Attempt <UrlInfo?> .Fail());
        }

        if (pcr.PublishedContent?.Id != content.Id)
        {
            IPublishedContent?o = pcr.PublishedContent;
            var l = new List <string>();
            while (o != null)
            {
                l.Add(o.Name(variationContextAccessor) !);
                o = o.Parent;
            }

            l.Reverse();
            var s = "/" + string.Join("/", l) + " (id=" + pcr.PublishedContent?.Id + ")";

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

        // no collision
        return(Attempt <UrlInfo?> .Fail());
    }
    // TODO: I feel like we need to do more than this, pretty sure we need to replace the UmbracoRouteValues
    // HttpRequest feature too while this renders.
    private void SetNewItemsOnContextObjects(IPublishedRequest request)
    {
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

        // now, set the new ones for this page execution
        umbracoContext.PublishedRequest = request;
    }
    // NOT thread-safe over a request because it modifies the
    // global UmbracoContext.Current.InPreviewMode status. So it
    // should never execute in // over the same UmbracoContext with
    // different preview modes.
    private string RenderRteMacros(string source, bool preview)
    {
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

        using (umbracoContext.ForcedPreview(preview)) // force for macro rendering
        {
            var sb = new StringBuilder();

            MacroTagParser.ParseMacros(
                source,

                // callback for when text block is found
                textBlock => sb.Append(textBlock),

                // callback for when macro syntax is found
                (macroAlias, macroAttributes) => sb.Append(_macroRenderer.RenderAsync(
                                                               macroAlias,
                                                               umbracoContext.PublishedRequest?.PublishedContent,

                                                               // needs to be explicitly casted to Dictionary<string, object>
                                                               macroAttributes.ConvertTo(x => (string)x, x => x) !).GetAwaiter().GetResult().Text));

            return(sb.ToString());
        }
    }
Example #12
0
    // stores macro content into the cache
    private async Task AddMacroContentToCacheAsync(MacroModel model, MacroContent macroContent)
    {
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

        // only if cache is enabled
        if (umbracoContext.InPreviewMode || model.CacheDuration <= 0)
        {
            return;
        }

        // do not cache if it should cache by member and there's not member
        if (model.CacheByMember)
        {
            IMemberManager?memberManager =
                _httpContextAccessor.HttpContext?.RequestServices.GetRequiredService <IMemberManager>();
            MemberIdentityUser?member = await memberManager?.GetCurrentMemberAsync() !;

            if (member is null)
            {
                return;
            }
        }

        // remember when we cache the content
        macroContent.Date = DateTime.Now;

        IAppPolicyCache cache = _appCaches.RuntimeCache;

        cache.Insert(
            CacheKeys.MacroContentCacheKey + model.CacheIdentifier,
            () => macroContent,
            new TimeSpan(0, 0, model.CacheDuration));

        _logger.LogDebug("Macro content saved to cache '{MacroCacheId}'", model.CacheIdentifier);
    }
    public async Task Lookup_By_Url_Alias(
        string relativeUrl,
        int nodeMatch,
        [Frozen] IPublishedContentCache publishedContentCache,
        [Frozen] IUmbracoContextAccessor umbracoContextAccessor,
        [Frozen] IUmbracoContext umbracoContext,
        [Frozen] IVariationContextAccessor variationContextAccessor,
        IFileService fileService,
        ContentFinderByUrlAlias sut,
        IPublishedContent[] rootContents,
        IPublishedProperty urlProperty)
    {
        // Arrange
        var absoluteUrl      = "http://localhost" + relativeUrl;
        var variationContext = new VariationContext();

        var contentItem = rootContents[0];

        Mock.Get(umbracoContextAccessor).Setup(x => x.TryGetUmbracoContext(out umbracoContext)).Returns(true);
        Mock.Get(umbracoContext).Setup(x => x.Content).Returns(publishedContentCache);
        Mock.Get(publishedContentCache).Setup(x => x.GetAtRoot(null)).Returns(rootContents);
        Mock.Get(contentItem).Setup(x => x.Id).Returns(nodeMatch);
        Mock.Get(contentItem).Setup(x => x.GetProperty(Constants.Conventions.Content.UrlAlias)).Returns(urlProperty);
        Mock.Get(urlProperty).Setup(x => x.GetValue(null, null)).Returns(relativeUrl);

        Mock.Get(variationContextAccessor).Setup(x => x.VariationContext).Returns(variationContext);
        var publishedRequestBuilder = new PublishedRequestBuilder(new Uri(absoluteUrl, UriKind.Absolute), fileService);

        // Act
        var result = await sut.TryFindContent(publishedRequestBuilder);

        Assert.IsTrue(result);
        Assert.AreEqual(publishedRequestBuilder.PublishedContent.Id, nodeMatch);
    }
Example #14
0
        public void Can_Lookup_Content()
        {
            var publishedSnapshot = new Mock <IPublishedSnapshot>();

            publishedSnapshot.Setup(x => x.Members).Returns(Mock.Of <IPublishedMemberCache>());
            var content = new Mock <IPublishedContent>();

            content.Setup(x => x.Id).Returns(2);
            IBackOfficeSecurityAccessor backofficeSecurityAccessor = Mock.Of <IBackOfficeSecurityAccessor>();

            Mock.Get(backofficeSecurityAccessor).Setup(x => x.BackOfficeSecurity).Returns(Mock.Of <IBackOfficeSecurity>());
            var publishedSnapshotService           = new Mock <IPublishedSnapshotService>();
            IHostingEnvironment hostingEnvironment = Mock.Of <IHostingEnvironment>();
            var globalSettings = new GlobalSettings();

            var umbracoContextFactory = TestUmbracoContextFactory.Create(globalSettings, _umbracoContextAccessor);

            UmbracoContextReference umbracoContextReference = umbracoContextFactory.EnsureUmbracoContext();
            IUmbracoContext         umbracoContext          = umbracoContextReference.UmbracoContext;

            var umbracoContextAccessor = new TestUmbracoContextAccessor(umbracoContext);

            IPublishedContentQuery publishedContentQuery = Mock.Of <IPublishedContentQuery>(query => query.Content(2) == content.Object);

            var ctrl   = new TestSurfaceController(umbracoContextAccessor, publishedContentQuery, Mock.Of <IPublishedUrlProvider>());
            var result = ctrl.GetContent(2) as PublishedContentResult;

            Assert.IsNotNull(result);
            Assert.IsNotNull(result.Content);
            Assert.AreEqual(2, result.Content.Id);
        }
    /// <summary>
    ///     Save all items that we know are used for rendering execution to variables so we can restore after rendering
    /// </summary>
    private void SaveExistingItems(out IPublishedRequest?oldPublishedRequest)
    {
        IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();

        // Many objects require that these legacy items are in the http context items... before we render this template we need to first
        // save the values in them so that we can re-set them after we render so the rest of the execution works as per normal
        oldPublishedRequest = umbracoContext.PublishedRequest;
    }
        /// <summary>
        /// Shared with PublishMediaStoreTests
        /// </summary>
        /// <param name="id"></param>
        /// <param name="umbracoContext"></param>
        /// <returns></returns>
        internal IPublishedContent GetNode(int id, IUmbracoContext umbracoContext)
        {
            var cache = new PublishedMediaCache(new XmlStore((XmlDocument)null, null, null, null, HostingEnvironment),
                                                ServiceContext.MediaService, ServiceContext.UserService, new DictionaryAppCache(), ContentTypesCache,
                                                Factory.GetRequiredService <IEntityXmlSerializer>(), Factory.GetRequiredService <IUmbracoContextAccessor>(), VariationContextAccessor);
            var doc = cache.GetById(id);

            Assert.IsNotNull(doc);
            return(doc);
        }
Example #17
0
        public string GetUrlFromRoute(int id, string?route, string?culture)
        {
            IUmbracoContext    umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
            DefaultUrlProvider?provider       = _urlProviders.OfType <DefaultUrlProvider>().FirstOrDefault();
            var url = provider == null
                ? route // what else?
                : provider.GetUrlFromRoute(route, umbracoContext, id, umbracoContext.CleanedUmbracoUrl, Mode, culture)?.Text;

            return(url ?? "#");
        }
    /// <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));
    }
Example #19
0
    private IPublishedUrlProvider GetPublishedUrlProvider(IUmbracoContext umbracoContext, DefaultUrlProvider urlProvider)
    {
        var webRoutingSettings = new WebRoutingSettings();

        return(new UrlProvider(
                   new TestUmbracoContextAccessor(umbracoContext),
                   Options.Create(webRoutingSettings),
                   new UrlProviderCollection(() => new[] { urlProvider }),
                   new MediaUrlProviderCollection(() => Enumerable.Empty <IMediaUrlProvider>()),
                   Mock.Of <IVariationContextAccessor>()));
    }
        private IPublishedUrlProvider GetPublishedUrlProvider(IUmbracoContext umbracoContext)
        {
            var webRoutingSettings = new WebRoutingSettings();

            return(new UrlProvider(
                       new TestUmbracoContextAccessor(umbracoContext),
                       Microsoft.Extensions.Options.Options.Create(webRoutingSettings),
                       new UrlProviderCollection(Enumerable.Empty <IUrlProvider>()),
                       new MediaUrlProviderCollection(new [] { _mediaUrlProvider }),
                       Mock.Of <IVariationContextAccessor>()
                       ));
        }
Example #21
0
        /// <inheritdoc />
        public UmbracoContextReference EnsureUmbracoContext()
        {
            if (_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext))
            {
                return(new UmbracoContextReference(umbracoContext, false, _umbracoContextAccessor));
            }

            IUmbracoContext createdUmbracoContext = CreateUmbracoContext();

            _umbracoContextAccessor.Set(createdUmbracoContext);
            return(new UmbracoContextReference(createdUmbracoContext, true, _umbracoContextAccessor));
        }
Example #22
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));
        }
    }
        private IUmbracoContext GetUmbracoContext(bool hasContent)
        {
            IPublishedContentCache publishedContent = Mock.Of <IPublishedContentCache>(x => x.HasContent() == hasContent);
            var uri = new Uri("http://example.com");

            IUmbracoContext umbracoContext = Mock.Of <IUmbracoContext>(x =>
                                                                       x.Content == publishedContent &&
                                                                       x.OriginalRequestUrl == uri &&
                                                                       x.CleanedUmbracoUrl == uri);

            return(umbracoContext);
        }
Example #24
0
        /// <inheritdoc />
        public virtual UrlInfo GetUrl(IPublishedContent content, UrlMode mode, string culture, Uri current)
        {
            if (!current.IsAbsoluteUri)
            {
                throw new ArgumentException("Current URL must be absolute.", nameof(current));
            }

            IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
            // will not use cache if previewing
            var route = umbracoContext.Content.GetRouteById(content.Id, culture);

            return(GetUrlFromRoute(route, umbracoContext, content.Id, current, mode, culture));
        }
        public async Task NoContentController_Values_When_No_Content()
        {
            IUmbracoContext umbracoContext = GetUmbracoContext(false);

            UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
                Mock.Of <IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)));

            RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());

            Assert.AreEqual(2, result.Count);
            Assert.AreEqual(ControllerExtensions.GetControllerName <RenderNoContentController>(), result[ControllerToken]);
            Assert.AreEqual(nameof(RenderNoContentController.Index), result[ActionToken]);
        }
Example #26
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);

            while (domainUris == null && n != null) // n is null at root
            {
                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));
            }
        }
Example #27
0
 /// <summary>
 ///     Generates a URL based on the current Umbraco URL with a custom query string that will route to the specified
 ///     SurfaceController
 /// </summary>
 /// <returns></returns>
 public static string SurfaceAction(
     this IUrlHelper url,
     IUmbracoContext umbracoContext,
     IDataProtectionProvider dataProtectionProvider,
     string action,
     string controllerName,
     object?additionalRouteVals) =>
 url.SurfaceAction(
     umbracoContext,
     dataProtectionProvider,
     action,
     controllerName,
     string.Empty,
     additionalRouteVals);
        public async Task Assigns_PublishedRequest_To_UmbracoContext()
        {
            IUmbracoContext   umbracoContext = GetUmbracoContext(true);
            IPublishedRequest request        = Mock.Of <IPublishedRequest>();

            UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
                Mock.Of <IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
                router: GetRouter(request),
                routeValuesFactory: GetRouteValuesFactory(request));

            RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());

            Assert.AreEqual(request, umbracoContext.PublishedRequest);
        }
        public async Task Returns_Null_RouteValueDictionary_When_No_Content()
        {
            IUmbracoContext    umbracoContext = GetUmbracoContext(true);
            IPublishedRequest  request        = Mock.Of <IPublishedRequest>(x => x.PublishedContent == null);
            UmbracoRouteValues routeValues    = GetRouteValues(request);

            UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
                Mock.Of <IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
                router: GetRouter(request),
                routeValuesFactory: GetRouteValuesFactory(request));

            RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());

            Assert.IsNull(result);
        }
        public async Task Assigns_Values_To_RouteValueDictionary_When_Content()
        {
            IUmbracoContext    umbracoContext = GetUmbracoContext(true);
            IPublishedRequest  request        = Mock.Of <IPublishedRequest>(x => x.PublishedContent == Mock.Of <IPublishedContent>());
            UmbracoRouteValues routeValues    = GetRouteValues(request);

            UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
                Mock.Of <IUmbracoContextAccessor>(x => x.TryGetUmbracoContext(out umbracoContext)),
                router: GetRouter(request),
                routeValuesFactory: GetRouteValuesFactory(request));

            RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());

            Assert.AreEqual(routeValues.ControllerName, result[ControllerToken]);
            Assert.AreEqual(routeValues.ActionName, result[ActionToken]);
        }
 public GlassRenderMvcController(IUmbracoContext umbracoContext)
 {
     UmbracoContext = umbracoContext;
 }