// initialize a PublishedContentCache instance with
        // an XmlStore containing the master xml
        // an IAppCache that should be at request-level
        // a RoutesCache - need to cleanup that one
        // a preview token string (or null if not previewing)
        public PublishedContentCache(
            XmlStore xmlStore,        // an XmlStore containing the master xml
            IDomainCache domainCache, // an IDomainCache implementation
            IAppCache appCache,       // an IAppCache that should be at request-level
            IGlobalSettings globalSettings,
            ISiteDomainHelper siteDomainHelper,
            IUmbracoContextAccessor umbracoContextAccessor,
            PublishedContentTypeCache contentTypeCache, // a PublishedContentType cache
            RoutesCache routesCache,                    // a RoutesCache
            string previewToken)                        // a preview token string (or null if not previewing)
            : base(previewToken.IsNullOrWhiteSpace() == false)
        {
            _appCache               = appCache;
            _globalSettings         = globalSettings;
            _umbracoContextAccessor = umbracoContextAccessor;
            _routesCache            = routesCache; // may be null for unit-testing
            _contentTypeCache       = contentTypeCache;
            _domainCache            = domainCache;
            _domainHelper           = new DomainHelper(_domainCache, siteDomainHelper);

            _xmlStore = xmlStore;
            _xml      = _xmlStore.Xml; // capture - because the cache has to remain consistent

            if (previewToken.IsNullOrWhiteSpace() == false)
            {
                _previewContent = new PreviewContent(_xmlStore, previewToken);
            }
        }
示例#2
0
        public static bool GetAssignedWithCulture(this IDomainCache domainCache, string culture, int documentId, bool includeWildcards = false)
        {
            var assigned = domainCache.GetAssigned(documentId, includeWildcards);

            // It's super important that we always compare cultures with ignore case, since we can't be sure of the casing!
            return(culture is null?assigned.Any() : assigned.Any(x => x.Culture.Equals(culture, StringComparison.InvariantCultureIgnoreCase)));
        }
示例#3
0
        // TODO: figure this out
        // after the current snapshot has been resync-ed
        // it's too late for UmbracoContext which has captured previewDefault and stuff into these ctor vars
        // but, no, UmbracoContext returns snapshot.Content which comes from elements SO a resync should create a new cache

        public ContentCache(bool previewDefault, ContentStore.Snapshot snapshot, IAppCache snapshotCache, IAppCache elementsCache, IDomainCache domainCache, IGlobalSettings globalSettings, IVariationContextAccessor variationContextAccessor)
            : base(previewDefault)
        {
            _snapshot                 = snapshot;
            _snapshotCache            = snapshotCache;
            _elementsCache            = elementsCache;
            _domainCache              = domainCache;
            _globalSettings           = globalSettings;
            _variationContextAccessor = variationContextAccessor;
        }
    public static bool GetAssignedWithCulture(this IDomainCache domainCache, string?culture, int documentId,
                                              bool includeWildcards = false)
    {
        IEnumerable <Domain> assigned = domainCache.GetAssigned(documentId, includeWildcards);

        // It's super important that we always compare cultures with ignore case, since we can't be sure of the casing!
        // Comparing with string.IsNullOrEmpty since both empty string and null signifies invariant.
        return(string.IsNullOrEmpty(culture)
            ? assigned.Any()
            : assigned.Any(x => x.Culture?.Equals(culture, StringComparison.InvariantCultureIgnoreCase) ?? false));
    }
示例#5
0
 // TODO: figure this out
 // after the current snapshot has been resync-ed
 // it's too late for UmbracoContext which has captured previewDefault and stuff into these ctor vars
 // but, no, UmbracoContext returns snapshot.Content which comes from elements SO a resync should create a new cache
 public ContentCache(
     bool previewDefault,
     ContentStore.Snapshot snapshot,
     IAppCache snapshotCache,
     IAppCache?elementsCache,
     IDomainCache domainCache,
     IOptions <GlobalSettings> globalSettings,
     IVariationContextAccessor variationContextAccessor)
     : base(previewDefault)
 {
     _snapshot                 = snapshot;
     _snapshotCache            = snapshotCache;
     _elementsCache            = elementsCache;
     _domainCache              = domainCache ?? throw new ArgumentNullException(nameof(domainCache));
     _globalSettings           = globalSettings.Value;
     _variationContextAccessor = variationContextAccessor;
 }
示例#6
0
        /// <summary>
        /// Finds the domain for the specified node, if any, that best matches a specified uri.
        /// </summary>
        /// <param name="domainCache">A domain cache.</param>
        /// <param name="siteDomainHelper">The site domain helper.</param>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="current">The uri, or null.</param>
        /// <param name="culture">The culture, or null.</param>
        /// <returns>The domain and its uri, if any, that best matches the specified uri and culture, else null.</returns>
        /// <remarks>
        /// <para>If at least a domain is set on the node then the method returns the domain that
        /// best matches the specified uri and culture, else it returns null.</para>
        /// <para>If culture is null, uses the default culture for the installation instead. Otherwise,
        /// will try with the specified culture, else return null.</para>
        /// </remarks>
        internal static DomainAndUri DomainForNode(IDomainCache domainCache, ISiteDomainHelper siteDomainHelper, int nodeId, Uri current, string culture = null)
        {
            // be safe
            if (nodeId <= 0)
            {
                return(null);
            }

            // get the domains on that node
            var domains = domainCache.GetAssigned(nodeId).ToArray();

            // none?
            if (domains.Length == 0)
            {
                return(null);
            }

            // else filter
            // it could be that none apply (due to culture)
            return(SelectDomain(domains, current, culture, domainCache.DefaultCulture, siteDomainHelper.MapDomain));
        }
示例#7
0
        /// <summary>
        /// Find the domains for the specified node, if any, that match a specified uri.
        /// </summary>
        /// <param name="domainCache">A domain cache.</param>
        /// <param name="siteDomainHelper">The site domain helper.</param>
        /// <param name="nodeId">The node identifier.</param>
        /// <param name="current">The uri, or null.</param>
        /// <param name="excludeDefault">A value indicating whether to exclude the current/default domain. True by default.</param>
        /// <returns>The domains and their uris, that match the specified uri, else null.</returns>
        /// <remarks>If at least a domain is set on the node then the method returns the domains that
        /// best match the specified uri, else it returns null.</remarks>
        internal static IEnumerable <DomainAndUri> DomainsForNode(IDomainCache domainCache, ISiteDomainHelper siteDomainHelper, int nodeId, Uri current, bool excludeDefault = true)
        {
            // be safe
            if (nodeId <= 0)
            {
                return(null);
            }

            // get the domains on that node
            var domains = domainCache.GetAssigned(nodeId).ToArray();

            // none?
            if (domains.Length == 0)
            {
                return(null);
            }

            // get the domains and their uris
            var domainAndUris = SelectDomains(domains, current).ToArray();

            // filter
            return(siteDomainHelper.MapDomains(domainAndUris, current, excludeDefault, null, domainCache.DefaultCulture).ToArray());
        }
示例#8
0
 public DomainHelper(IDomainCache domainCache, ISiteDomainHelper siteDomainHelper)
 {
     _domainCache      = domainCache;
     _siteDomainHelper = siteDomainHelper;
 }
示例#9
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.
            _logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, request.Uri);
            var          umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
            IDomainCache domainsCache   = umbracoContext.PublishedSnapshot.Domains;
            var          domains        = domainsCache.GetAll(includeWildcards: 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(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
                _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
                _logger.LogDebug("{TracePrefix}Matches no domain", tracePrefix);

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

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

            return(request.Domain != null);
        }
        public static bool GetAssignedWithCulture(this IDomainCache domainCache, string culture, int documentId, bool includeWildcards = false)
        {
            var assigned = domainCache.GetAssigned(documentId, includeWildcards);

            return(culture is null?assigned.Any() : assigned.Any(x => x.Culture == culture));
        }